diff --git a/DEPS b/DEPS
index 052195f..a49b25c 100644
--- a/DEPS
+++ b/DEPS
@@ -126,11 +126,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': 'a29dd9d0cb8ba8d7da29e293b52ff142f8a0e2f1',
+  'skia_revision': '26490759e46483558627c9132e31f4b97cf052ac',
   # 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': 'dd39fc4a68253921a82fa21037c0ab4547f219bc',
+  'v8_revision': '054df48cc27e6c74b54c9aac7a4386e9aed99a28',
   # 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.
@@ -138,11 +138,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': '088e521769f96374d7099dcc84ce998b42148fef',
+  'angle_revision': 'cd4f1fbaabce8edb9e0cbe04c5bd976c65fa776b',
   # 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': 'c81766320762e6a67dad91e6a41304f8713bc7d1',
+  'swiftshader_revision': '7fb0b73b1aa74b33c08258cef1fe800dc8a94e26',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
@@ -186,7 +186,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': '38769c1f96a321e99a04743d2326cab6ff8fa6fb',
+  'catapult_revision': '22b1689dde6c7c028db5e6a5dedc1249f0a30eaf',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -234,7 +234,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'spv_tools_revision': 'cf21146137cf1b51de0b963d1163c0c67d2c0662',
+  'spv_tools_revision': '10a7def6c03e29c4246a01577199aaf35e29f9f9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -729,7 +729,7 @@
 
   # Build tools for Chrome OS. Note: This depends on third_party/pyelftools.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'f2c1116f97a65f7660f2a01e7c5581e4fce23d08',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '43ecc6793a5c6b4962df615e644a2a79014b339c',
       'condition': 'checkout_linux',
   },
 
@@ -754,7 +754,7 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'b9ae2ca9a55d9b754c313f4c9e9f0f3b804a5e44',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '545f0d025ef1f93aa276c4da765f5450013014dc',
 
   'src/third_party/devtools-node-modules':
     Var('chromium_git') + '/external/github.com/ChromeDevTools/devtools-node-modules' + '@' + Var('devtools_node_modules_revision'),
@@ -1089,7 +1089,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' +  '413f0052c89e45e424129b8a946da9c46f002452',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' +  'ee4a5ccc89d4c97d5128ca9df51ecfdbbb3643ee',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + 'ac0d98b5cee6c024b0cffeb4f8f45b6fc5ccdb78',
@@ -1293,7 +1293,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@ff3805a634568c9e54155e427de97b98153371dc',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@79ffba7a9de64764b6690629fcb9f467074ed56f',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index 70e61dc..cffe099 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -184,19 +184,19 @@
     case 1:
       wallpaper_controller->ShowWallpaperImage(
           CreateWallpaperImage(SK_ColorRED, SK_ColorBLUE), info,
-          false /*preview_mode=*/);
+          /*preview_mode=*/false, /*always_on_top=*/false);
       break;
     case 2:
       info.layout = WALLPAPER_LAYOUT_CENTER;
       wallpaper_controller->ShowWallpaperImage(
           CreateWallpaperImage(SK_ColorBLUE, SK_ColorGREEN), info,
-          false /*preview_mode=*/);
+          /*preview_mode=*/false, /*always_on_top=*/false);
       break;
     case 3:
       info.layout = WALLPAPER_LAYOUT_CENTER_CROPPED;
       wallpaper_controller->ShowWallpaperImage(
           CreateWallpaperImage(SK_ColorGREEN, SK_ColorRED), info,
-          false /*preview_mode=*/);
+          /*preview_mode=*/false, /*always_on_top=*/false);
       break;
   }
 }
diff --git a/ash/app_list/model/app_list_folder_item.cc b/ash/app_list/model/app_list_folder_item.cc
index 020aac5..d180ab7 100644
--- a/ash/app_list/model/app_list_folder_item.cc
+++ b/ash/app_list/model/app_list_folder_item.cc
@@ -62,6 +62,10 @@
   return true;
 }
 
+bool AppListFolderItem::ShouldAutoRemove() const {
+  return ChildItemCount() <= (is_persistent() ? 0u : 1u);
+}
+
 std::string AppListFolderItem::GenerateId() {
   return base::GenerateGUID();
 }
diff --git a/ash/app_list/model/app_list_folder_item.h b/ash/app_list/model/app_list_folder_item.h
index 760c504..6baaf16 100644
--- a/ash/app_list/model/app_list_folder_item.h
+++ b/ash/app_list/model/app_list_folder_item.h
@@ -67,6 +67,14 @@
   size_t ChildItemCount() const override;
   bool CompareForTest(const AppListItem* other) const override;
 
+  // Persistent folders will be retained even if there is 1 app in them.
+  bool is_persistent() const { return is_persistent_; }
+  void set_is_persistent(bool is_persistent) { is_persistent_ = is_persistent; }
+
+  // Returns true if this folder is a candidate for auto-removal (based on its
+  // type and the number of children it has).
+  bool ShouldAutoRemove() const;
+
   // Returns an id for a new folder.
   static std::string GenerateId();
 
@@ -84,6 +92,8 @@
   // List of items in the folder.
   std::unique_ptr<AppListItemList> item_list_;
 
+  bool is_persistent_ = false;
+
   FolderImage folder_image_;
 
   DISALLOW_COPY_AND_ASSIGN(AppListFolderItem);
diff --git a/ash/app_list/model/app_list_model.cc b/ash/app_list/model/app_list_model.cc
index a96cce4..f75c947 100644
--- a/ash/app_list/model/app_list_model.cc
+++ b/ash/app_list/model/app_list_model.cc
@@ -274,10 +274,10 @@
   const std::string folder_id = item->folder_id();
   DeleteItem(id);
 
-  // crbug.com/368111: Upon uninstall of 2nd-to-last folder item, reparent last
-  // item to top; this will remove the folder.
+  // crbug.com/368111: Deleting a child item may cause the parent folder to be
+  // auto-removed.
   AppListFolderItem* folder = FindFolderItem(folder_id);
-  if (folder && folder->ChildItemCount() == 1u) {
+  if (folder && folder->ShouldAutoRemove()) {
     AppListItem* last_item = folder->item_list()->item_at(0);
     MoveItemToFolderAt(last_item, "", folder->position());
   }
diff --git a/ash/app_list/model/app_list_model_unittest.cc b/ash/app_list/model/app_list_model_unittest.cc
index 92acbea..349c757 100644
--- a/ash/app_list/model/app_list_model_unittest.cc
+++ b/ash/app_list/model/app_list_model_unittest.cc
@@ -444,6 +444,26 @@
   EXPECT_EQ("Item 0", GetModelContents());
 }
 
+TEST_F(AppListModelFolderTest, UninstallPersistentFolderItem) {
+  AppListItem* item0 = model_.CreateAndAddItem("Item 0");
+  AppListItem* item1 = model_.CreateAndAddItem("Item 1");
+  AppListFolderItem* folder1 = static_cast<AppListFolderItem*>(
+      model_.AddItem(new AppListFolderItem("folder1")));
+  folder1->set_is_persistent(true);
+  EXPECT_EQ("Item 0,Item 1,folder1", GetModelContents());
+
+  // Move all items to folder1.
+  model_.MoveItemToFolderAt(item0, folder1->id(), item0->position());
+  model_.MoveItemToFolderAt(item1, folder1->id(), item1->position());
+  EXPECT_EQ("Item 0,Item 1", GetItemListContents(folder1->item_list()));
+  EXPECT_EQ("folder1", GetModelContents());
+
+  // Delete Item from folder.
+  model_.DeleteUninstalledItem("Item 1");
+  ASSERT_EQ("folder1", GetModelContents());
+  EXPECT_EQ("Item 0", GetItemListContents(folder1->item_list()));
+}
+
 TEST_F(AppListModelFolderTest, UninstallSingleItemFolderItem) {
   AppListItem* item0 = model_.CreateAndAddItem("Item 0");
   AppListFolderItem* folder1 = static_cast<AppListFolderItem*>(
diff --git a/ash/app_list/views/apps_grid_view.cc b/ash/app_list/views/apps_grid_view.cc
index 02560ac..7282294 100644
--- a/ash/app_list/views/apps_grid_view.cc
+++ b/ash/app_list/views/apps_grid_view.cc
@@ -2031,10 +2031,10 @@
   int target_model_index = GetTargetModelIndexForMove(item_view, target);
   int target_item_index = GetTargetItemIndexForMove(item_view, target);
 
-  // Remove the source folder view if there is only 1 item in it, since the
-  // source folder will be deleted after its only child item removed from it.
+  // If the folder is a candidate for removal, the view needs to be updated
+  // accordingly.
   GridIndex target_override = target;
-  if (source_folder->ChildItemCount() == 1u) {
+  if (source_folder->ShouldAutoRemove()) {
     const int deleted_folder_index =
         view_model_.GetIndexOfView(activated_folder_item_view_);
     const GridIndex deleted_folder_grid_index =
@@ -2104,10 +2104,8 @@
   // Make change to data model.
   item_list_->RemoveObserver(this);
 
-  // Remove the source folder view if there is only 1 item in it, since the
-  // source folder will be deleted after its only child item merged into the
-  // target item.
-  if (source_folder->ChildItemCount() == 1u) {
+  // Remove the source folder view if the folder is a candidate for removal.
+  if (source_folder->ShouldAutoRemove()) {
     DeleteItemViewAtIndex(
         view_model_.GetIndexOfView(activated_folder_item_view()),
         false /* sanitize */);
@@ -2173,7 +2171,7 @@
     const std::string& source_folder_id) {
   AppListFolderItem* source_folder =
       static_cast<AppListFolderItem*>(item_list_->FindItem(source_folder_id));
-  if (!source_folder || source_folder->ChildItemCount() != 1u)
+  if (!source_folder || !source_folder->ShouldAutoRemove())
     return;
 
   // Save the folder item view's bounds before deletion, which will be used as
diff --git a/ash/assistant/ui/BUILD.gn b/ash/assistant/ui/BUILD.gn
index bb46a713..1a707a0 100644
--- a/ash/assistant/ui/BUILD.gn
+++ b/ash/assistant/ui/BUILD.gn
@@ -40,8 +40,6 @@
     "assistant_mini_view.h",
     "assistant_notification_overlay.cc",
     "assistant_notification_overlay.h",
-    "assistant_notification_view.cc",
-    "assistant_notification_view.h",
     "assistant_overlay.h",
     "assistant_view_delegate.h",
     "assistant_web_view.cc",
diff --git a/ash/assistant/ui/assistant_container_view.cc b/ash/assistant/ui/assistant_container_view.cc
index 9eab091..9ec04c9 100644
--- a/ash/assistant/ui/assistant_container_view.cc
+++ b/ash/assistant/ui/assistant_container_view.cc
@@ -70,7 +70,7 @@
 
       int left = layout_params.margins.left();
       int top = layout_params.margins.top();
-      int width = std::min(preferred_size.width(), this->width());
+      int width = preferred_size.width();
       int height = preferred_size.height();
 
       // Gravity::kBottom.
@@ -79,10 +79,8 @@
         top = this->height() - height - layout_params.margins.bottom();
 
       // Gravity::kCenterHorizontal.
-      if ((layout_params.gravity & Gravity::kCenterHorizontal) != 0) {
-        width = std::min(width, this->width() - layout_params.margins.width());
-        left = (this->width() - width) / 2;
-      }
+      if ((layout_params.gravity & Gravity::kCenterHorizontal) != 0)
+        left = (this->width() - width) / 2 - layout_params.margins.left();
 
       overlay->SetBounds(left, top, width, height);
     }
diff --git a/ash/assistant/ui/assistant_notification_overlay.cc b/ash/assistant/ui/assistant_notification_overlay.cc
index a19a3d3..6f8133f 100644
--- a/ash/assistant/ui/assistant_notification_overlay.cc
+++ b/ash/assistant/ui/assistant_notification_overlay.cc
@@ -4,10 +4,7 @@
 
 #include "ash/assistant/ui/assistant_notification_overlay.h"
 
-#include <memory>
-
-#include "ash/assistant/ui/assistant_notification_view.h"
-#include "ui/views/layout/fill_layout.h"
+#include "ui/gfx/canvas.h"
 
 namespace ash {
 
@@ -15,7 +12,8 @@
 
 // Appearance.
 constexpr int kMarginBottomDip = 64;
-constexpr int kMarginHorizontalDip = 32;
+constexpr int kPreferredHeightDip = 60;
+constexpr int kPreferredWidthDip = 576;
 
 }  // namespace
 
@@ -29,24 +27,31 @@
   return "AssistantNotificationOverlay";
 }
 
+gfx::Size AssistantNotificationOverlay::CalculatePreferredSize() const {
+  return gfx::Size(kPreferredWidthDip, GetHeightForWidth(kPreferredWidthDip));
+}
+
+int AssistantNotificationOverlay::GetHeightForWidth(int width) const {
+  return kPreferredHeightDip;
+}
+
 AssistantOverlay::LayoutParams AssistantNotificationOverlay::GetLayoutParams()
     const {
   using Gravity = AssistantOverlay::LayoutParams::Gravity;
   AssistantOverlay::LayoutParams layout_params;
   layout_params.gravity = Gravity::kBottom | Gravity::kCenterHorizontal;
-  layout_params.margins = gfx::Insets(0, kMarginHorizontalDip, kMarginBottomDip,
-                                      kMarginHorizontalDip);
+  layout_params.margins = gfx::Insets(0, 0, kMarginBottomDip, 0);
   return layout_params;
 }
 
-void AssistantNotificationOverlay::InitLayout() {
-  SetLayoutManager(std::make_unique<views::FillLayout>());
+// TODO(dmblack): Remove when notification views have been implemented.
+void AssistantNotificationOverlay::OnPaintBackground(gfx::Canvas* canvas) {
+  canvas->DrawColor(0x20000000);
+}
 
+void AssistantNotificationOverlay::InitLayout() {
   SetPaintToLayer();
   layer()->SetFillsBoundsOpaquely(false);
-
-  // TODO(dmblack): Wire up to actual notifications.
-  AddChildView(new AssistantNotificationView());
 }
 
 };  // namespace ash
diff --git a/ash/assistant/ui/assistant_notification_overlay.h b/ash/assistant/ui/assistant_notification_overlay.h
index 0c5a74f..1f6a1037 100644
--- a/ash/assistant/ui/assistant_notification_overlay.h
+++ b/ash/assistant/ui/assistant_notification_overlay.h
@@ -21,7 +21,10 @@
 
   // AssistantOverlay:
   const char* GetClassName() const override;
+  gfx::Size CalculatePreferredSize() const override;
+  int GetHeightForWidth(int width) const override;
   LayoutParams GetLayoutParams() const override;
+  void OnPaintBackground(gfx::Canvas* canvas) override;
 
  private:
   void InitLayout();
diff --git a/ash/assistant/ui/assistant_notification_view.cc b/ash/assistant/ui/assistant_notification_view.cc
deleted file mode 100644
index ab34db2..0000000
--- a/ash/assistant/ui/assistant_notification_view.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/assistant/ui/assistant_notification_view.h"
-
-#include <string>
-
-#include "ash/assistant/ui/assistant_ui_constants.h"
-#include "ash/assistant/ui/main_stage/suggestion_chip_view.h"
-#include "base/strings/utf_string_conversions.h"
-#include "ui/views/animation/ink_drop_painted_layer_delegates.h"
-#include "ui/views/controls/button/button.h"
-#include "ui/views/controls/label.h"
-#include "ui/views/layout/box_layout.h"
-#include "ui/views/layout/fill_layout.h"
-
-namespace ash {
-
-namespace {
-
-// Appearance.
-constexpr int kLineHeightDip = 20;
-constexpr int kPaddingLeftDip = 16;
-constexpr int kPaddingRightDip = 8;
-constexpr int kPreferredHeightDip = 48;
-constexpr int kShadowElevationDip = 6;
-
-// Helpers ---------------------------------------------------------------------
-
-views::View* CreateButton(const std::string& label) {
-  SuggestionChipView::Params params;
-  params.text = base::UTF8ToUTF16(label);
-  return new SuggestionChipView(params, /*listener=*/nullptr);
-}
-
-}  // namespace
-
-AssistantNotificationView::AssistantNotificationView() {
-  InitLayout();
-}
-
-AssistantNotificationView::~AssistantNotificationView() = default;
-
-const char* AssistantNotificationView::GetClassName() const {
-  return "AssistantNotificationView";
-}
-
-gfx::Size AssistantNotificationView::CalculatePreferredSize() const {
-  return gfx::Size(INT_MAX, GetHeightForWidth(INT_MAX));
-}
-
-int AssistantNotificationView::GetHeightForWidth(int width) const {
-  return kPreferredHeightDip;
-}
-
-void AssistantNotificationView::OnBoundsChanged(
-    const gfx::Rect& previous_bounds) {
-  UpdateBackground();
-}
-
-void AssistantNotificationView::InitLayout() {
-  SetLayoutManager(std::make_unique<views::FillLayout>());
-
-  SetPaintToLayer();
-  layer()->SetFillsBoundsOpaquely(false);
-
-  // Background/shadow.
-  background_layer_.SetFillsBoundsOpaquely(false);
-  layer()->Add(&background_layer_);
-
-  // Container.
-  views::View* container = new views::View();
-  container->SetPreferredSize(gfx::Size(INT_MAX, INT_MAX));
-  container->SetPaintToLayer();
-  container->layer()->SetFillsBoundsOpaquely(false);
-  AddChildView(container);
-
-  auto* layout_manager =
-      container->SetLayoutManager(std::make_unique<views::BoxLayout>(
-          views::BoxLayout::Orientation::kHorizontal,
-          gfx::Insets(0, kPaddingLeftDip, 0, kPaddingRightDip), kSpacingDip));
-
-  layout_manager->set_cross_axis_alignment(
-      views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER);
-
-  gfx::FontList font_list =
-      assistant::ui::GetDefaultFontList().DeriveWithSizeDelta(1);
-
-  // Title.
-  auto* title = new views::Label(base::UTF8ToUTF16("Placeholder Title"));
-  title->SetAutoColorReadabilityEnabled(false);
-  title->SetEnabledColor(kTextColorPrimary);
-  title->SetFontList(font_list.DeriveWithWeight(gfx::Font::Weight::MEDIUM));
-  title->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
-  title->SetLineHeight(kLineHeightDip);
-  container->AddChildView(title);
-
-  // Message.
-  auto* message = new views::Label(base::UTF8ToUTF16("Placeholder Message"));
-  message->SetAutoColorReadabilityEnabled(false);
-  message->SetEnabledColor(kTextColorSecondary);
-  message->SetFontList(font_list);
-  message->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
-  message->SetLineHeight(kLineHeightDip);
-  container->AddChildView(message);
-
-  layout_manager->SetFlexForView(message, 1);
-
-  // Buttons.
-  container->AddChildView(CreateButton("Placeholder Button 1"));
-  container->AddChildView(CreateButton("Placeholder Button 2"));
-}
-
-void AssistantNotificationView::UpdateBackground() {
-  gfx::ShadowValues shadow_values =
-      gfx::ShadowValue::MakeMdShadowValues(kShadowElevationDip);
-
-  shadow_delegate_ = std::make_unique<views::BorderShadowLayerDelegate>(
-      shadow_values, GetLocalBounds(),
-      /*fill_color=*/SK_ColorWHITE,
-      /*corner_radius=*/height() / 2);
-
-  background_layer_.set_delegate(shadow_delegate_.get());
-  background_layer_.SetBounds(
-      gfx::ToEnclosingRect(shadow_delegate_->GetPaintedBounds()));
-}
-
-}  // namespace ash
diff --git a/ash/assistant/ui/assistant_notification_view.h b/ash/assistant/ui/assistant_notification_view.h
deleted file mode 100644
index da2bb5d..0000000
--- a/ash/assistant/ui/assistant_notification_view.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_VIEW_H_
-#define ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_VIEW_H_
-
-#include <memory>
-
-#include "base/component_export.h"
-#include "base/macros.h"
-#include "ui/compositor/layer.h"
-#include "ui/views/view.h"
-
-namespace views {
-class BorderShadowLayerDelegate;
-}  // namespace views
-
-namespace ash {
-
-// AssistantNotificationView is the view for a mojom::AssistantNotification
-// which appears in Assistant UI. Its parent is AssistantNotificationOverlay.
-class COMPONENT_EXPORT(ASSISTANT_UI) AssistantNotificationView
-    : public views::View {
- public:
-  AssistantNotificationView();
-  ~AssistantNotificationView() override;
-
-  // views::View:
-  const char* GetClassName() const override;
-  gfx::Size CalculatePreferredSize() const override;
-  int GetHeightForWidth(int width) const override;
-  void OnBoundsChanged(const gfx::Rect& previous_bounds) override;
-
- private:
-  void InitLayout();
-  void UpdateBackground();
-
-  // Background/shadow.
-  ui::Layer background_layer_;
-  std::unique_ptr<views::BorderShadowLayerDelegate> shadow_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(AssistantNotificationView);
-};
-
-}  // namespace ash
-
-#endif  // ASH_ASSISTANT_UI_ASSISTANT_NOTIFICATION_VIEW_H_
diff --git a/ash/assistant/ui/assistant_ui_constants.h b/ash/assistant/ui/assistant_ui_constants.h
index 79b589a6..eb74d035f 100644
--- a/ash/assistant/ui/assistant_ui_constants.h
+++ b/ash/assistant/ui/assistant_ui_constants.h
@@ -25,8 +25,8 @@
 constexpr int kUiElementHorizontalMarginDip = 32;
 
 // Typography.
+constexpr SkColor kTextColorHint = gfx::kGoogleGrey700;
 constexpr SkColor kTextColorPrimary = gfx::kGoogleGrey900;
-constexpr SkColor kTextColorSecondary = gfx::kGoogleGrey700;
 
 // TODO(dmblack): Move the other constants into ash::assistant::ui.
 namespace assistant {
diff --git a/ash/assistant/ui/dialog_plate/dialog_plate.cc b/ash/assistant/ui/dialog_plate/dialog_plate.cc
index c454cb9..3735d3f 100644
--- a/ash/assistant/ui/dialog_plate/dialog_plate.cc
+++ b/ash/assistant/ui/dialog_plate/dialog_plate.cc
@@ -327,7 +327,7 @@
       l10n_util::GetStringUTF16(IDS_ASH_ASSISTANT_DIALOG_PLATE_HINT);
   textfield_->set_placeholder_text(textfield_hint);
   textfield_->SetAccessibleName(textfield_hint);
-  textfield_->set_placeholder_text_color(kTextColorSecondary);
+  textfield_->set_placeholder_text_color(kTextColorHint);
   textfield_->SetTextColor(kTextColorPrimary);
   keyboard_layout_container_->AddChildView(textfield_);
 
diff --git a/ash/assistant/ui/main_stage/assistant_query_view.cc b/ash/assistant/ui/main_stage/assistant_query_view.cc
index 4792450..b910aed 100644
--- a/ash/assistant/ui/main_stage/assistant_query_view.cc
+++ b/ash/assistant/ui/main_stage/assistant_query_view.cc
@@ -128,7 +128,7 @@
       label_->AddStyleRange(gfx::Range(high_confidence_text_16.length(),
                                        high_confidence_text_16.length() +
                                            low_confidence_text_16.length()),
-                            CreateStyleInfo(kTextColorSecondary));
+                            CreateStyleInfo(kTextColorHint));
     }
   }
   label_->SizeToFit(width());
diff --git a/ash/assistant/ui/main_stage/suggestion_chip_view.h b/ash/assistant/ui/main_stage/suggestion_chip_view.h
index b8eeb535..b0573fa 100644
--- a/ash/assistant/ui/main_stage/suggestion_chip_view.h
+++ b/ash/assistant/ui/main_stage/suggestion_chip_view.h
@@ -18,7 +18,6 @@
 
 namespace ash {
 
-// TODO(dmblack): Move to /ash/assistant/ui/base/.
 // View representing a suggestion chip.
 class COMPONENT_EXPORT(ASSISTANT_UI) SuggestionChipView : public views::Button {
  public:
diff --git a/ash/public/cpp/shell_window_ids.h b/ash/public/cpp/shell_window_ids.h
index 1532c8a..1ad8e33 100644
--- a/ash/public/cpp/shell_window_ids.h
+++ b/ash/public/cpp/shell_window_ids.h
@@ -135,6 +135,10 @@
   // The container for mouse cursor.
   kShellWindowId_MouseCursorContainer,
 
+  // The container for an image that should stay on top of everything except for
+  // the power off animation.
+  kShellWindowId_AlwaysOnTopWallpaperContainer,
+
   // The topmost container, used for power off animation.
   kShellWindowId_PowerButtonAnimationContainer,
 
@@ -181,6 +185,7 @@
     kShellWindowId_OverlayContainer,
     kShellWindowId_DockedMagnifierContainer,
     kShellWindowId_MouseCursorContainer,
+    kShellWindowId_AlwaysOnTopWallpaperContainer,
     kShellWindowId_PowerButtonAnimationContainer,
 };
 
diff --git a/ash/public/interfaces/wallpaper.mojom b/ash/public/interfaces/wallpaper.mojom
index 6601ff3..bb5df37 100644
--- a/ash/public/interfaces/wallpaper.mojom
+++ b/ash/public/interfaces/wallpaper.mojom
@@ -205,6 +205,17 @@
   // when using this method.
   ShowOneShotWallpaper(gfx.mojom.ImageSkia image);
 
+  // Shows a wallpaper that stays on top of everything except for the power off
+  // animation. All other wallpaper requests are ignored when the always-on-top
+  // wallpaper is being shown.
+  // |image_path|: The file path to read the image data from.
+  ShowAlwaysOnTopWallpaper(mojo_base.mojom.FilePath image_path);
+
+  // Removes the always-on-top wallpaper. The wallpaper will revert to the
+  // previous one, or a default one if there was none. No-op if the current
+  // wallpaper is not always-on-top.
+  RemoveAlwaysOnTopWallpaper();
+
   // Removes all of the user's saved wallpapers and related info.
   // |wallpaper_files_id|: The file id for user_info.account_id.
   RemoveUserWallpaper(WallpaperUserInfo user_info, string wallpaper_files_id);
diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc
index 4318b30..5bbf827 100644
--- a/ash/root_window_controller.cc
+++ b/ash/root_window_controller.cc
@@ -1016,6 +1016,9 @@
                       "MouseCursorContainer", screen_rotation_container);
   mouse_cursor_container->SetProperty(::wm::kUsesScreenCoordinatesKey, true);
 
+  CreateContainer(kShellWindowId_AlwaysOnTopWallpaperContainer,
+                  "AlwaysOnTopWallpaperContainer", screen_rotation_container);
+
   CreateContainer(kShellWindowId_PowerButtonAnimationContainer,
                   "PowerButtonAnimationContainer", screen_rotation_container);
 }
diff --git a/ash/wallpaper/wallpaper_controller.cc b/ash/wallpaper/wallpaper_controller.cc
index 1e252f3..e57d457 100644
--- a/ash/wallpaper/wallpaper_controller.cc
+++ b/ash/wallpaper/wallpaper_controller.cc
@@ -641,7 +641,12 @@
 
 void WallpaperController::ShowWallpaperImage(const gfx::ImageSkia& image,
                                              WallpaperInfo info,
-                                             bool preview_mode) {
+                                             bool preview_mode,
+                                             bool always_on_top) {
+  // Prevent showing other wallpapers if there is an always-on-top wallpaper.
+  if (is_always_on_top_wallpaper_ && !always_on_top)
+    return;
+
   // Ignore show wallpaper requests during preview mode. This could happen if a
   // custom wallpaper previously set on another device is being synced.
   if (confirm_preview_wallpaper_callback_ && !preview_mode)
@@ -896,7 +901,7 @@
                             weak_factory_.GetWeakPtr(), image,
                             WallpaperInfo{std::string(), layout, CUSTOMIZED,
                                           base::Time::Now().LocalMidnight()},
-                            /*preview_mode=*/true);
+                            /*preview_mode=*/true, /*always_on_top=*/false);
     // Show the preview wallpaper.
     reload_preview_wallpaper_callback_.Run();
   } else {
@@ -1145,7 +1150,8 @@
   // hit (e.g. when the first time the wallpaper is shown on login screen).
   gfx::ImageSkia user_wallpaper;
   if (GetWallpaperFromCache(account_id, &user_wallpaper)) {
-    ShowWallpaperImage(user_wallpaper, info, /*preview_mode=*/false);
+    ShowWallpaperImage(user_wallpaper, info, /*preview_mode=*/false,
+                       /*always_on_top=*/false);
     return;
   }
 
@@ -1209,7 +1215,27 @@
   const WallpaperInfo info = {
       std::string(), WallpaperLayout::WALLPAPER_LAYOUT_STRETCH,
       WallpaperType::ONE_SHOT, base::Time::Now().LocalMidnight()};
-  ShowWallpaperImage(image, info, /*preview_mode=*/false);
+  ShowWallpaperImage(image, info, /*preview_mode=*/false,
+                     /*always_on_top=*/false);
+}
+
+void WallpaperController::ShowAlwaysOnTopWallpaper(
+    const base::FilePath& image_path) {
+  is_always_on_top_wallpaper_ = true;
+  const WallpaperInfo info = {
+      std::string(), WallpaperLayout::WALLPAPER_LAYOUT_CENTER_CROPPED,
+      WallpaperType::ONE_SHOT, base::Time::Now().LocalMidnight()};
+  ReadAndDecodeWallpaper(
+      base::BindOnce(&WallpaperController::OnAlwaysOnTopWallpaperDecoded,
+                     weak_factory_.GetWeakPtr(), info),
+      sequenced_task_runner_, image_path);
+}
+
+void WallpaperController::RemoveAlwaysOnTopWallpaper() {
+  if (!is_always_on_top_wallpaper_)
+    return;
+  is_always_on_top_wallpaper_ = false;
+  ReloadWallpaper(/*clear_cache=*/false);
 }
 
 void WallpaperController::RemoveUserWallpaper(
@@ -1484,6 +1510,9 @@
 }
 
 int WallpaperController::GetWallpaperContainerId(bool locked) {
+  if (is_always_on_top_wallpaper_)
+    return kShellWindowId_AlwaysOnTopWallpaperContainer;
+
   return locked ? kShellWindowId_LockScreenWallpaperContainer
                 : kShellWindowId_WallpaperContainer;
 }
@@ -1694,7 +1723,7 @@
                             weak_factory_.GetWeakPtr(), image,
                             WallpaperInfo{params.url, params.layout, ONLINE,
                                           base::Time::Now().LocalMidnight()},
-                            /*preview_mode=*/true);
+                            /*preview_mode=*/true, /*always_on_top=*/false);
     // Show the preview wallpaper.
     reload_preview_wallpaper_callback_.Run();
   } else {
@@ -1713,8 +1742,10 @@
     LOG(ERROR) << "Setting user wallpaper info fails. This should never happen "
                   "except in tests.";
   }
-  if (show_wallpaper)
-    ShowWallpaperImage(image, wallpaper_info, /*preview_mode=*/false);
+  if (show_wallpaper) {
+    ShowWallpaperImage(image, wallpaper_info, /*preview_mode=*/false,
+                       /*always_on_top=*/false);
+  }
 
   wallpaper_cache_map_[params.account_id] =
       CustomWallpaperElement(base::FilePath(), image);
@@ -1797,7 +1828,7 @@
     WallpaperInfo info(cached_default_wallpaper_.file_path.value(), layout,
                        DEFAULT, base::Time::Now().LocalMidnight());
     ShowWallpaperImage(cached_default_wallpaper_.image, info,
-                       /*preview_mode=*/false);
+                       /*preview_mode=*/false, /*always_on_top=*/false);
   }
 }
 
@@ -1853,8 +1884,10 @@
                        layout, base::Passed(std::move(deep_copy))));
   }
 
-  if (show_wallpaper)
-    ShowWallpaperImage(image, info, /*preview_mode=*/false);
+  if (show_wallpaper) {
+    ShowWallpaperImage(image, info, /*preview_mode=*/false,
+                       /*always_on_top=*/false);
+  }
 
   wallpaper_cache_map_[user_info->account_id] =
       CustomWallpaperElement(wallpaper_path, image);
@@ -1876,8 +1909,10 @@
   }
 
   wallpaper_cache_map_[account_id] = CustomWallpaperElement(path, image);
-  if (show_wallpaper)
-    ShowWallpaperImage(image, info, /*preview_mode=*/false);
+  if (show_wallpaper) {
+    ShowWallpaperImage(image, info, /*preview_mode=*/false,
+                       /*always_on_top=*/false);
+  }
 }
 
 void WallpaperController::ReloadWallpaper(bool clear_cache) {
@@ -1988,6 +2023,21 @@
   return cached_colors_out;
 }
 
+void WallpaperController::OnAlwaysOnTopWallpaperDecoded(
+    const WallpaperInfo& info,
+    const gfx::ImageSkia& image) {
+  // Do nothing if |RemoveAlwaysOnTopWallpaper| was called before decoding
+  // completes.
+  if (!is_always_on_top_wallpaper_)
+    return;
+  if (image.isNull()) {
+    is_always_on_top_wallpaper_ = false;
+    return;
+  }
+  ShowWallpaperImage(image, info, /*preview_mode=*/false,
+                     /*always_on_top=*/true);
+}
+
 bool WallpaperController::MoveToLockedContainer() {
   if (locked_)
     return false;
@@ -2049,7 +2099,8 @@
     WallpaperInfo info(device_policy_wallpaper_path_.value(),
                        WALLPAPER_LAYOUT_CENTER_CROPPED, DEVICE,
                        base::Time::Now().LocalMidnight());
-    ShowWallpaperImage(image, info, /*preview_mode=*/false);
+    ShowWallpaperImage(image, info, /*preview_mode=*/false,
+                       /*always_on_top=*/false);
   }
 }
 
diff --git a/ash/wallpaper/wallpaper_controller.h b/ash/wallpaper/wallpaper_controller.h
index be67f35..3c95cde 100644
--- a/ash/wallpaper/wallpaper_controller.h
+++ b/ash/wallpaper/wallpaper_controller.h
@@ -153,12 +153,15 @@
   // always return true thereafter.
   bool HasShownAnyWallpaper() const;
 
-  // Shows the wallpaper and alerts observers of changes. Does not show the
-  // image if |preview_mode| is false and the current wallpaper is still being
-  // previewed. See comments for |confirm_preview_wallpaper_callback_|.
+  // Shows the wallpaper and alerts observers of changes.
+  // Does not show the image if:
+  // 1)  |preview_mode| is false and the current wallpaper is still being
+  //     previewed. See comments for |confirm_preview_wallpaper_callback_|.
+  // 2)  |always_on_top| is false but the current wallpaper is always-on-top.
   void ShowWallpaperImage(const gfx::ImageSkia& image,
                           WallpaperInfo info,
-                          bool preview_mode);
+                          bool preview_mode,
+                          bool always_on_top);
 
   // Returns whether a wallpaper policy is enforced for |account_id| (not
   // including device policy).
@@ -262,6 +265,8 @@
   void ShowUserWallpaper(mojom::WallpaperUserInfoPtr user_info) override;
   void ShowSigninWallpaper() override;
   void ShowOneShotWallpaper(const gfx::ImageSkia& image) override;
+  void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override;
+  void RemoveAlwaysOnTopWallpaper() override;
   void RemoveUserWallpaper(mojom::WallpaperUserInfoPtr user_info,
                            const std::string& wallpaper_files_id) override;
   void RemovePolicyWallpaper(mojom::WallpaperUserInfoPtr user_info,
@@ -500,6 +505,10 @@
   base::Optional<std::vector<SkColor>> GetCachedColors(
       const std::string& current_location) const;
 
+  // The callback when decoding of the always-on-top wallpaper completes.
+  void OnAlwaysOnTopWallpaperDecoded(const WallpaperInfo& info,
+                                     const gfx::ImageSkia& image);
+
   // Move all wallpaper widgets to the locked container.
   // Returns true if the wallpaper moved.
   bool MoveToLockedContainer();
@@ -603,6 +612,9 @@
   // controller initialization. Empty wallpapers for testing don't count.
   bool is_first_wallpaper_ = false;
 
+  // If true, the current wallpaper should always stay on top.
+  bool is_always_on_top_wallpaper_ = false;
+
   scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_;
 
   ScopedSessionObserver scoped_session_observer_;
diff --git a/ash/wallpaper/wallpaper_controller_test_api.cc b/ash/wallpaper/wallpaper_controller_test_api.cc
index df5e97ac..fcf6e349 100644
--- a/ash/wallpaper/wallpaper_controller_test_api.cc
+++ b/ash/wallpaper/wallpaper_controller_test_api.cc
@@ -34,7 +34,7 @@
 SkColor WallpaperControllerTestApi::ApplyColorProducingWallpaper() {
   controller_->ShowWallpaperImage(
       CreateImageWithColor(SkColorSetRGB(60, 40, 40)), kTestWallpaperInfo,
-      false /*preview_mode=*/);
+      /*preview_mode=*/false, /*always_on_top=*/false);
   return SkColorSetRGB(18, 12, 12);
 }
 
@@ -46,12 +46,12 @@
                      controller_->weak_factory_.GetWeakPtr(),
                      AccountId::FromUserEmail("user@test.com"),
                      user_manager::USER_TYPE_REGULAR, kTestWallpaperInfo,
-                     true /*show_wallpaper=*/);
-  controller_->reload_preview_wallpaper_callback_ =
-      base::BindRepeating(&WallpaperController::ShowWallpaperImage,
-                          controller_->weak_factory_.GetWeakPtr(),
-                          CreateImageWithColor(SK_ColorBLUE),
-                          kTestWallpaperInfo, true /*preview_mode=*/);
+                     /*show_wallpaper=*/true);
+  controller_->reload_preview_wallpaper_callback_ = base::BindRepeating(
+      &WallpaperController::ShowWallpaperImage,
+      controller_->weak_factory_.GetWeakPtr(),
+      CreateImageWithColor(SK_ColorBLUE), kTestWallpaperInfo,
+      /*preview_mode=*/true, /*always_on_top=*/false);
   // Show the preview wallpaper.
   controller_->reload_preview_wallpaper_callback_.Run();
 }
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc
index 8082a87c..0b06fe1 100644
--- a/ash/wallpaper/wallpaper_controller_unittest.cc
+++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -352,7 +352,7 @@
     const gfx::ImageSkia kImage = CreateImage(10, 10, kWallpaperColor);
     controller_->ShowWallpaperImage(
         kImage, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
-        false /*preview_mode=*/);
+        /*preview_mode=*/false, /*always_on_top=*/false);
     SetSessionState(SessionState::ACTIVE);
 
     EXPECT_TRUE(ShouldCalculateColors());
@@ -535,6 +535,10 @@
 
   void ClearWallpaper() { controller_->current_wallpaper_.reset(); }
 
+  int GetWallpaperContainerId() {
+    return controller_->GetWallpaperContainerId(controller_->locked_);
+  }
+
   WallpaperController* controller_;  // Not owned.
 
   base::ScopedTempDir user_data_dir_;
@@ -694,9 +698,9 @@
 
   // Set the image as custom wallpaper, wait for the resize to finish, and check
   // that the resized image is the expected size.
-  controller_->ShowWallpaperImage(image,
-                                  CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
-                                  false /*preview_mode=*/);
+  controller_->ShowWallpaperImage(
+      image, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
+      /*preview_mode=*/false, /*always_on_top=*/false);
   EXPECT_TRUE(image.BackedBySameObjectAs(controller_->GetWallpaper()));
   RunAllTasksUntilIdle();
   gfx::ImageSkia resized_image = controller_->GetWallpaper();
@@ -706,9 +710,9 @@
   // Load the original wallpaper again and check that we're still using the
   // previously-resized image instead of doing another resize
   // (http://crbug.com/321402).
-  controller_->ShowWallpaperImage(image,
-                                  CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
-                                  false /*preview_mode=*/);
+  controller_->ShowWallpaperImage(
+      image, CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
+      /*preview_mode=*/false, /*always_on_top=*/false);
   RunAllTasksUntilIdle();
   EXPECT_TRUE(resized_image.BackedBySameObjectAs(controller_->GetWallpaper()));
 }
@@ -767,7 +771,7 @@
     SCOPED_TRACE(base::StringPrintf("1200x600*2 high resolution"));
     controller_->ShowWallpaperImage(
         image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
-        false /*preview_mode=*/);
+        /*preview_mode=*/false, /*always_on_top=*/false);
     WallpaperFitToNativeResolution(wallpaper_view(), high_dsf,
                                    high_resolution.width(),
                                    high_resolution.height(), kWallpaperColor);
@@ -776,7 +780,7 @@
     SCOPED_TRACE(base::StringPrintf("1200x600*2 low resolution"));
     controller_->ShowWallpaperImage(
         image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
-        false /*preview_mode=*/);
+        /*preview_mode=*/false, /*always_on_top=*/false);
     WallpaperFitToNativeResolution(wallpaper_view(), high_dsf,
                                    low_resolution.width(),
                                    low_resolution.height(), kWallpaperColor);
@@ -787,7 +791,7 @@
     SCOPED_TRACE(base::StringPrintf("1200x600 high resolution"));
     controller_->ShowWallpaperImage(
         image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
-        false /*preview_mode=*/);
+        /*preview_mode=*/false, /*always_on_top=*/false);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    high_resolution.width(),
                                    high_resolution.height(), kWallpaperColor);
@@ -796,7 +800,7 @@
     SCOPED_TRACE(base::StringPrintf("1200x600 low resolution"));
     controller_->ShowWallpaperImage(
         image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
-        false /*preview_mode=*/);
+        /*preview_mode=*/false, /*always_on_top=*/false);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    low_resolution.width(),
                                    low_resolution.height(), kWallpaperColor);
@@ -807,7 +811,7 @@
     SCOPED_TRACE(base::StringPrintf("1200x600/u@1.5 high resolution"));
     controller_->ShowWallpaperImage(
         image_high_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
-        false /*preview_mode=*/);
+        /*preview_mode=*/false, /*always_on_top=*/false);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    high_resolution.width(),
                                    high_resolution.height(), kWallpaperColor);
@@ -816,7 +820,7 @@
     SCOPED_TRACE(base::StringPrintf("1200x600/u@1.5 low resolution"));
     controller_->ShowWallpaperImage(
         image_low_res, CreateWallpaperInfo(WALLPAPER_LAYOUT_CENTER),
-        false /*preview_mode=*/);
+        /*preview_mode=*/false, /*always_on_top=*/false);
     WallpaperFitToNativeResolution(wallpaper_view(), low_dsf,
                                    low_resolution.width(),
                                    low_resolution.height(), kWallpaperColor);
@@ -2428,7 +2432,8 @@
   // Show the first wallpaper, verify the observer is notified.
   controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorBLUE),
                                   CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
-                                  false /*preview_mode=*/);
+                                  /*preview_mode=*/false,
+                                  /*always_on_top=*/false);
   RunAllTasksUntilIdle();
   EXPECT_EQ(SK_ColorBLUE, GetWallpaperColor());
   EXPECT_EQ(1, GetWallpaperCount());
@@ -2436,7 +2441,8 @@
   // Show the second wallpaper, verify the observer is not notified.
   controller_->ShowWallpaperImage(CreateImage(640, 480, SK_ColorCYAN),
                                   CreateWallpaperInfo(WALLPAPER_LAYOUT_STRETCH),
-                                  false /*preview_mode=*/);
+                                  /*preview_mode=*/false,
+                                  /*always_on_top=*/false);
   RunAllTasksUntilIdle();
   EXPECT_EQ(SK_ColorCYAN, GetWallpaperColor());
   EXPECT_EQ(2, GetWallpaperCount());
@@ -2488,6 +2494,55 @@
   EXPECT_EQ(kWallpaperColor, GetWallpaperColor());
 }
 
+TEST_F(WallpaperControllerTest, AlwaysOnTopWallpaper) {
+  CreateDefaultWallpapers();
+  SetBypassDecode();
+
+  // Show a default wallpaper.
+  EXPECT_EQ(0, GetWallpaperCount());
+  controller_->ShowSigninWallpaper();
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(1, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), DEFAULT);
+  EXPECT_EQ(kShellWindowId_WallpaperContainer, GetWallpaperContainerId());
+
+  // Show an always-on-top wallpaper.
+  const base::FilePath image_path =
+      base::CommandLine::ForCurrentProcess()->GetSwitchValuePath(
+          chromeos::switches::kGuestWallpaperLarge);
+  controller_->ShowAlwaysOnTopWallpaper(image_path);
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(2, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), ONE_SHOT);
+  EXPECT_EQ(kShellWindowId_AlwaysOnTopWallpaperContainer,
+            GetWallpaperContainerId());
+
+  // Subsequent wallpaper requests are ignored when the current wallpaper is
+  // always-on-top.
+  controller_->ShowSigninWallpaper();
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(2, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), ONE_SHOT);
+  EXPECT_EQ(kShellWindowId_AlwaysOnTopWallpaperContainer,
+            GetWallpaperContainerId());
+
+  // The wallpaper reverts to the default after the always-on-top wallpaper is
+  // removed.
+  controller_->RemoveAlwaysOnTopWallpaper();
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(3, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), DEFAULT);
+  EXPECT_EQ(kShellWindowId_WallpaperContainer, GetWallpaperContainerId());
+
+  // Calling |RemoveAlwaysOnTopWallpaper| is a no-op when the current wallpaper
+  // is not always-on-top.
+  controller_->RemoveAlwaysOnTopWallpaper();
+  RunAllTasksUntilIdle();
+  EXPECT_EQ(3, GetWallpaperCount());
+  EXPECT_EQ(controller_->GetWallpaperType(), DEFAULT);
+  EXPECT_EQ(kShellWindowId_WallpaperContainer, GetWallpaperContainerId());
+}
+
 // A test wallpaper controller client class.
 class TestWallpaperControllerClient : public mojom::WallpaperControllerClient {
  public:
diff --git a/base/base_switches.cc b/base/base_switches.cc
index 23514e3..ff781a3 100644
--- a/base/base_switches.cc
+++ b/base/base_switches.cc
@@ -8,7 +8,7 @@
 namespace switches {
 
 // Delays execution of base::TaskPriority::BEST_EFFORT tasks until shutdown.
-const char kDisableBackgroundTasks[] = "disable-background-tasks";
+const char kDisableBestEffortTasks[] = "disable-best-effort-tasks";
 
 // Disables the crash reporting.
 const char kDisableBreakpad[]               = "disable-breakpad";
diff --git a/base/base_switches.h b/base/base_switches.h
index a22cd29..5967c1a 100644
--- a/base/base_switches.h
+++ b/base/base_switches.h
@@ -11,7 +11,7 @@
 
 namespace switches {
 
-extern const char kDisableBackgroundTasks[];
+extern const char kDisableBestEffortTasks[];
 extern const char kDisableBreakpad[];
 extern const char kDisableFeatures[];
 extern const char kDisableLowEndDeviceMode[];
diff --git a/base/task/task_scheduler/task_tracker.cc b/base/task/task_scheduler/task_tracker.cc
index fb14f99..80ca168 100644
--- a/base/task/task_scheduler/task_tracker.cc
+++ b/base/task/task_scheduler/task_tracker.cc
@@ -142,7 +142,7 @@
   // in a dynamic library which doesn't have access to argc/argv.
   if (CommandLine::InitializedForCurrentProcess() &&
       CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kDisableBackgroundTasks)) {
+          switches::kDisableBestEffortTasks)) {
     return 0;
   }
   return std::numeric_limits<int>::max();
diff --git a/base/task/task_scheduler/task_tracker.h b/base/task/task_scheduler/task_tracker.h
index 667b18b..a85875e2 100644
--- a/base/task/task_scheduler/task_tracker.h
+++ b/base/task/task_scheduler/task_tracker.h
@@ -98,7 +98,7 @@
   // |histogram_label| is used as a suffix for histograms, it must not be empty.
   // The first constructor sets the maximum number of TaskPriority::BEST_EFFORT
   // sequences that can be scheduled concurrently to 0 if the
-  // --disable-background-tasks flag is specified, max() otherwise. The second
+  // --disable-best-effort-tasks flag is specified, max() otherwise. The second
   // constructor sets it to |max_num_scheduled_best_effort_sequences|.
   TaskTracker(StringPiece histogram_label);
   TaskTracker(StringPiece histogram_label,
diff --git a/base/trace_event/trace_arguments.cc b/base/trace_event/trace_arguments.cc
index 642ba23..d3f7124 100644
--- a/base/trace_event/trace_arguments.cc
+++ b/base/trace_event/trace_arguments.cc
@@ -42,7 +42,7 @@
 }
 
 // Append |val| as a JSON output value to |*out|.
-void AppendDoubleAsJSON(double val, std::string* out) {
+void AppendDouble(double val, bool as_json, std::string* out) {
   // FIXME: base/json/json_writer.cc is using the same code,
   //        should be made into a common method.
   std::string real;
@@ -67,11 +67,11 @@
   } else if (std::isnan(val)) {
     // The JSON spec doesn't allow NaN and Infinity (since these are
     // objects in EcmaScript).  Use strings instead.
-    real = "\"NaN\"";
+    real = as_json ? "\"NaN\"" : "NaN";
   } else if (val < 0) {
-    real = "\"-Infinity\"";
+    real = as_json ? "\"-Infinity\"" : "-Infinity";
   } else {
-    real = "\"Infinity\"";
+    real = as_json ? "\"Infinity\"" : "Infinity";
   }
   StringAppendF(out, "%s", real.c_str());
 }
@@ -139,6 +139,16 @@
     "TraceValue must be plain-old-data type for performance reasons!");
 
 void TraceValue::AppendAsJSON(unsigned char type, std::string* out) const {
+  Append(type, true, out);
+}
+
+void TraceValue::AppendAsString(unsigned char type, std::string* out) const {
+  Append(type, false, out);
+}
+
+void TraceValue::Append(unsigned char type,
+                        bool as_json,
+                        std::string* out) const {
   switch (type) {
     case TRACE_VALUE_TYPE_BOOL:
       *out += this->as_bool ? "true" : "false";
@@ -150,18 +160,24 @@
       StringAppendF(out, "%" PRId64, static_cast<int64_t>(this->as_int));
       break;
     case TRACE_VALUE_TYPE_DOUBLE:
-      AppendDoubleAsJSON(this->as_double, out);
+      AppendDouble(this->as_double, as_json, out);
       break;
-    case TRACE_VALUE_TYPE_POINTER:
+    case TRACE_VALUE_TYPE_POINTER: {
       // JSON only supports double and int numbers.
       // So as not to lose bits from a 64-bit pointer, output as a hex string.
+      // For consistency, do the same for non-JSON strings, but without the
+      // surrounding quotes.
+      const char* format_string = as_json ? "\"0x%" PRIx64 "\"" : "0x%" PRIx64;
       StringAppendF(
-          out, "\"0x%" PRIx64 "\"",
+          out, format_string,
           static_cast<uint64_t>(reinterpret_cast<uintptr_t>(this->as_pointer)));
-      break;
+    } break;
     case TRACE_VALUE_TYPE_STRING:
     case TRACE_VALUE_TYPE_COPY_STRING:
-      EscapeJSONString(this->as_string ? this->as_string : "NULL", true, out);
+      if (as_json)
+        EscapeJSONString(this->as_string ? this->as_string : "NULL", true, out);
+      else
+        *out += this->as_string ? this->as_string : "NULL";
       break;
     case TRACE_VALUE_TYPE_CONVERTABLE:
       this->as_convertable->AppendAsTraceFormat(out);
diff --git a/base/trace_event/trace_arguments.h b/base/trace_event/trace_arguments.h
index 6a9af808..0abc1279 100644
--- a/base/trace_event/trace_arguments.h
+++ b/base/trace_event/trace_arguments.h
@@ -260,7 +260,14 @@
   // TRACE_VALUE_TYPE_XXX value.
   void AppendAsJSON(unsigned char type, std::string* out) const;
 
+  // Output current value as a string. If the output string is to be used
+  // in a JSON format use AppendAsJSON instead. |type| must be valid
+  // TRACE_VALUE_TYPE_XXX value.
+  void AppendAsString(unsigned char type, std::string* out) const;
+
  private:
+  void Append(unsigned char type, bool as_json, std::string* out) const;
+
   // InnerType<T>::type removes reference, cv-qualifications and decays
   // function and arrays into pointers. Only used internally.
   template <typename T>
diff --git a/base/trace_event/trace_arguments_unittest.cc b/base/trace_event/trace_arguments_unittest.cc
index 787ff55..9f3544b5 100644
--- a/base/trace_event/trace_arguments_unittest.cc
+++ b/base/trace_event/trace_arguments_unittest.cc
@@ -5,6 +5,7 @@
 #include "base/trace_event/trace_arguments.h"
 
 #include <gtest/gtest.h>
+#include <limits>
 #include <string>
 
 namespace base {
@@ -87,22 +88,69 @@
   EXPECT_STREQ(expected, out.c_str());
 }
 
-TEST(TraceArguments, TraceValueAppendAsJSON) {
+static void CheckStringFor(TraceValue v, char type, const char* expected) {
+  std::string out;
+  v.AppendAsString(type, &out);
+  EXPECT_STREQ(expected, out.c_str());
+}
+
+TEST(TraceArguments, TraceValueAppend) {
   TraceValue v;
 
   v.Init(-1024);
   CheckJSONFor(v, TRACE_VALUE_TYPE_INT, "-1024");
+  CheckStringFor(v, TRACE_VALUE_TYPE_INT, "-1024");
   v.Init(1024ULL);
   CheckJSONFor(v, TRACE_VALUE_TYPE_UINT, "1024");
+  CheckStringFor(v, TRACE_VALUE_TYPE_UINT, "1024");
   v.Init(3.1415926535);
   CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "3.1415926535");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "3.1415926535");
+  v.Init(2.0);
+  CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "2.0");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "2.0");
+  v.Init(0.5);
+  CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "0.5");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "0.5");
+  v.Init(-0.5);
+  CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "-0.5");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "-0.5");
+  v.Init(std::numeric_limits<double>::quiet_NaN());
+  CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "\"NaN\"");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "NaN");
+  v.Init(std::numeric_limits<double>::quiet_NaN());
+  CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "\"NaN\"");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "NaN");
+  v.Init(std::numeric_limits<double>::infinity());
+  CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "\"Infinity\"");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "Infinity");
+  v.Init(-std::numeric_limits<double>::infinity());
+  CheckJSONFor(v, TRACE_VALUE_TYPE_DOUBLE, "\"-Infinity\"");
+  CheckStringFor(v, TRACE_VALUE_TYPE_DOUBLE, "-Infinity");
   v.Init(true);
   CheckJSONFor(v, TRACE_VALUE_TYPE_BOOL, "true");
+  CheckStringFor(v, TRACE_VALUE_TYPE_BOOL, "true");
   v.Init(false);
   CheckJSONFor(v, TRACE_VALUE_TYPE_BOOL, "false");
+  CheckStringFor(v, TRACE_VALUE_TYPE_BOOL, "false");
   v.Init("Some \"nice\" String");
   CheckJSONFor(v, TRACE_VALUE_TYPE_STRING, "\"Some \\\"nice\\\" String\"");
+  CheckStringFor(v, TRACE_VALUE_TYPE_STRING, "Some \"nice\" String");
   CheckJSONFor(v, TRACE_VALUE_TYPE_COPY_STRING, "\"Some \\\"nice\\\" String\"");
+  CheckStringFor(v, TRACE_VALUE_TYPE_COPY_STRING, "Some \"nice\" String");
+
+  int* p = nullptr;
+  v.Init(p);
+  CheckJSONFor(v, TRACE_VALUE_TYPE_POINTER, "\"0x0\"");
+  CheckStringFor(v, TRACE_VALUE_TYPE_POINTER, "0x0");
+
+  const char kText[] = "Hello World";
+  bool destroy_flag = false;
+  TraceArguments args("arg1",
+                      std::make_unique<MyConvertable>(kText, &destroy_flag));
+
+  CheckJSONFor(std::move(args.values()[0]), args.types()[0], kText);
+  CheckStringFor(std::move(args.values()[0]), args.types()[0], kText);
 }
 
 TEST(TraceArguments, DefaultConstruction) {
diff --git a/base/trace_event/trace_event_etw_export_win.cc b/base/trace_event/trace_event_etw_export_win.cc
index fc6a2547..bdf4036 100644
--- a/base/trace_event/trace_event_etw_export_win.cc
+++ b/base/trace_event/trace_event_etw_export_win.cc
@@ -238,7 +238,7 @@
       // created exceed WPA's 4094 byte limit and are shown as:
       // "Unable to parse data". See crbug.com/488257
     } else {
-      args->values()[i].AppendAsJSON(args->types()[i], arg_values_string + i);
+      args->values()[i].AppendAsString(args->types()[i], arg_values_string + i);
     }
   }
 
diff --git a/chrome/VERSION b/chrome/VERSION
index 649a35c4e..94c600e9 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=74
 MINOR=0
-BUILD=3699
+BUILD=3700
 PATCH=0
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt
index 4151efc..f497227 100644
--- a/chrome/android/profiles/newest.txt
+++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-74.0.3690.0_rc-r1.afdo.bz2
\ No newline at end of file
+chromeos-chrome-amd64-74.0.3698.0_rc-r1.afdo.bz2
\ No newline at end of file
diff --git a/chrome/app/BUILD.gn b/chrome/app/BUILD.gn
index cd02268..2ff64e1 100644
--- a/chrome/app/BUILD.gn
+++ b/chrome/app/BUILD.gn
@@ -436,7 +436,7 @@
     "//components/services/heap_profiling/public/mojom",
     "//components/translate/content/common",
     "//extensions/buildflags",
-    "//services/identity:manifest",
+    "//services/identity/public/cpp:manifest",
     "//services/image_annotation/public/cpp:manifest",
     "//services/preferences/public/cpp:manifest",
     "//services/service_manager/public/cpp",
@@ -458,16 +458,16 @@
       "//ash/components/tap_visualizer/public/cpp:manifest",
       "//ash/components/tap_visualizer/public/mojom",
       "//chromeos/assistant:buildflags",
-      "//chromeos/services/device_sync:manifest",
+      "//chromeos/services/device_sync/public/cpp:manifest",
       "//chromeos/services/ime/public/mojom",
       "//chromeos/services/media_perception/public/mojom",
-      "//chromeos/services/multidevice_setup:manifest",
+      "//chromeos/services/multidevice_setup/public/cpp:manifest",
       "//chromeos/services/multidevice_setup/public/mojom",
       "//ui/accessibility/mojom",
     ]
 
     if (enable_cros_assistant) {
-      deps += [ "//chromeos/services/assistant:manifest" ]
+      deps += [ "//chromeos/services/assistant/public/cpp:manifest" ]
     }
   }
 
@@ -561,15 +561,15 @@
     "//chrome/common:mojo_bindings",
     "//chrome/services/file_util/public/cpp:manifest",
     "//chrome/services/noop/public/cpp:manifest",
-    "//components/services/patch:manifest",
-    "//components/services/unzip:manifest",
+    "//components/services/patch/public/cpp:manifest",
+    "//components/services/unzip/public/cpp:manifest",
     "//components/spellcheck/common:interfaces",
     "//components/startup_metric_utils/common:interfaces",
     "//device/vr/buildflags",
     "//extensions/buildflags",
     "//printing/buildflags",
     "//services/preferences/public/cpp:local_state_manifest",
-    "//services/proxy_resolver:proxy_resolver_manifest",
+    "//services/proxy_resolver/public/cpp:manifest",
     "//services/service_manager/public/cpp",
   ]
 
@@ -582,7 +582,7 @@
   }
 
   if (enable_basic_printing) {
-    deps += [ "//components/services/pdf_compositor:pdf_compositor_manifest" ]
+    deps += [ "//components/services/pdf_compositor/public/cpp:manifest" ]
   }
 
   if (enable_print_preview) {
@@ -595,7 +595,7 @@
 
   if (enable_simple_browser_service_in_process ||
       enable_simple_browser_service_out_of_process) {
-    deps += [ "//services/content/simple_browser:manifest" ]
+    deps += [ "//services/content/simple_browser/public/cpp:manifest" ]
   }
 
   if (is_win) {
@@ -613,8 +613,8 @@
       "//ash/public/cpp:manifest",
       "//chrome/browser/chromeos:ash_pref_connector_manifest",
       "//chrome/services/cups_ipp_parser/public/cpp:manifest",
-      "//chromeos/services/ime:manifest",
-      "//chromeos/services/secure_channel:manifest",
+      "//chromeos/services/ime/public/cpp:manifest",
+      "//chromeos/services/secure_channel/public/cpp:manifest",
       "//mash/public/mojom",
       "//services/ws/public/mojom/input_devices",
       "//ui/accessibility:manifest",
diff --git a/chrome/app/DEPS b/chrome/app/DEPS
index 66afec5..039bbff 100644
--- a/chrome/app/DEPS
+++ b/chrome/app/DEPS
@@ -97,9 +97,9 @@
     "+chromeos/services/ime",
     "+chromeos/services/secure_channel",
     "+components/mirroring/service",
-    "+components/services/patch",
+    "+components/services/patch/public",
     "+components/services/pdf_compositor",
-    "+components/services/unzip",
+    "+components/services/unzip/public",
     "+components/spellcheck/common",
     "+components/startup_metric_utils/common",
     "+device/vr/buildflags",
diff --git a/chrome/app/chrome_content_browser_overlay_manifest.cc b/chrome/app/chrome_content_browser_overlay_manifest.cc
index 318f0a2..de1a1a6 100644
--- a/chrome/app/chrome_content_browser_overlay_manifest.cc
+++ b/chrome/app/chrome_content_browser_overlay_manifest.cc
@@ -36,7 +36,7 @@
 #include "components/services/heap_profiling/public/mojom/heap_profiling_client.mojom.h"
 #include "components/translate/content/common/translate.mojom.h"
 #include "extensions/buildflags/buildflags.h"
-#include "services/identity/manifest.h"
+#include "services/identity/public/cpp/manifest.h"
 #include "services/image_annotation/public/cpp/manifest.h"
 #include "services/image_annotation/public/mojom/constants.mojom.h"
 #include "services/image_annotation/public/mojom/image_annotation.mojom.h"
@@ -55,15 +55,15 @@
 #include "ash/components/tap_visualizer/public/cpp/manifest.h"  // nogncheck
 #include "ash/components/tap_visualizer/public/mojom/tap_visualizer.mojom.h"  // nogncheck
 #include "chromeos/assistant/buildflags.h"  // nogncheck
-#include "chromeos/services/device_sync/manifest.h"
+#include "chromeos/services/device_sync/public/cpp/manifest.h"
 #include "chromeos/services/ime/public/mojom/input_engine.mojom.h"
 #include "chromeos/services/media_perception/public/mojom/media_perception.mojom.h"
-#include "chromeos/services/multidevice_setup/manifest.h"
+#include "chromeos/services/multidevice_setup/public/cpp/manifest.h"
 #include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
 #include "services/ws/common/switches.h"
 #include "ui/accessibility/mojom/ax_host.mojom.h"  // nogncheck
 #if BUILDFLAG(ENABLE_CROS_ASSISTANT)
-#include "chromeos/services/assistant/manifest.h"  // nogncheck
+#include "chromeos/services/assistant/public/cpp/manifest.h"  // nogncheck
 #endif
 #endif
 
@@ -252,10 +252,10 @@
             .PackageService(image_annotation::GetManifest())
             .PackageService(prefs::GetManifest())
 #if defined(OS_CHROMEOS)
-            .PackageService(device_sync::GetManifest())
-            .PackageService(multidevice_setup::GetManifest())
+            .PackageService(chromeos::device_sync::GetManifest())
+            .PackageService(chromeos::multidevice_setup::GetManifest())
 #if BUILDFLAG(ENABLE_CROS_ASSISTANT)
-            .PackageService(assistant::GetManifest())
+            .PackageService(chromeos::assistant::GetManifest())
 #endif
 #endif  // defined(OS_CHROMEOS)
 #if !defined(OS_ANDROID)
diff --git a/chrome/app/chrome_packaged_service_manifests.cc b/chrome/app/chrome_packaged_service_manifests.cc
index 3b80fe73..dbbd02c5 100644
--- a/chrome/app/chrome_packaged_service_manifests.cc
+++ b/chrome/app/chrome_packaged_service_manifests.cc
@@ -10,15 +10,15 @@
 #include "chrome/common/constants.mojom.h"
 #include "chrome/services/file_util/public/cpp/manifest.h"
 #include "chrome/services/noop/public/cpp/manifest.h"
-#include "components/services/patch/manifest.h"
-#include "components/services/unzip/manifest.h"
+#include "components/services/patch/public/cpp/manifest.h"
+#include "components/services/unzip/public/cpp/manifest.h"
 #include "components/spellcheck/common/spellcheck.mojom.h"
 #include "components/startup_metric_utils/common/startup_metric.mojom.h"
 #include "device/vr/buildflags/buildflags.h"
 #include "extensions/buildflags/buildflags.h"
 #include "printing/buildflags/buildflags.h"
 #include "services/preferences/public/cpp/local_state_manifest.h"
-#include "services/proxy_resolver/proxy_resolver_manifest.h"
+#include "services/proxy_resolver/public/cpp/manifest.h"
 #include "services/service_manager/public/cpp/manifest_builder.h"
 
 #if defined(OS_CHROMEOS)
@@ -28,8 +28,8 @@
 #include "ash/public/cpp/manifest.h"
 #include "chrome/browser/chromeos/prefs/ash_pref_connector_manifest.h"
 #include "chrome/services/cups_ipp_parser/public/cpp/manifest.h"
-#include "chromeos/services/ime/manifest.h"
-#include "chromeos/services/secure_channel/manifest.h"
+#include "chromeos/services/ime/public/cpp/manifest.h"
+#include "chromeos/services/secure_channel/public/cpp/manifest.h"
 #include "mash/public/mojom/launchable.mojom.h"  // nogncheck
 #include "services/ws/public/mojom/input_devices/input_device_controller.mojom.h"
 #include "ui/accessibility/manifest.h"  // nogncheck
@@ -58,7 +58,7 @@
 #endif
 
 #if BUILDFLAG(ENABLE_PRINTING)
-#include "components/services/pdf_compositor/pdf_compositor_manifest.h"  // nogncheck
+#include "components/services/pdf_compositor/public/cpp/manifest.h"  // nogncheck
 #endif
 
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
@@ -71,7 +71,7 @@
 
 #if BUILDFLAG(ENABLE_SIMPLE_BROWSER_SERVICE_IN_PROCESS) || \
     BUILDFLAG(ENABLE_SIMPLE_BROWSER_SERVICE_OUT_OF_PROCESS)
-#include "services/content/simple_browser/manifest.h"  // nogncheck
+#include "services/content/simple_browser/public/cpp/manifest.h"  // nogncheck
 #endif
 
 namespace {
@@ -135,8 +135,8 @@
       GetChromeManifest(),
       GetFileUtilManifest(),
       GetNoopManifest(),
-      patch_service::GetManifest(),
-      unzip_service::GetManifest(),
+      patch::GetManifest(),
+      unzip::GetManifest(),
       proxy_resolver::GetManifest(),
       prefs::GetLocalStateManifest(),
 #if BUILDFLAG(ENABLE_EXTENSIONS)
@@ -146,7 +146,7 @@
       GetMediaGalleryUtilManifest(),
 #endif
 #if BUILDFLAG(ENABLE_PRINTING)
-      pdf_compositor::GetManifest(),
+      printing::GetPdfCompositorManifest(),
 #endif
 #if BUILDFLAG(ENABLE_PRINT_PREVIEW)
       GetChromePrintingManifest(),
@@ -175,8 +175,8 @@
       ash::GetManifest(),
       GetAshPrefConnectorManifest(),
       GetCupsIppParserManifest(),
-      ime::GetManifest(),
-      secure_channel::GetManifest(),
+      chromeos::ime::GetManifest(),
+      chromeos::secure_channel::GetManifest(),
       ax_host_service::GetManifest(),
 #endif
   }};
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index ccc463e..7796250 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -3507,13 +3507,9 @@
     An error occurred during uninstallation. Please uninstall through the Terminal.
   </message>
 
-  <!-- Crostini Repository Search -->
-  <message name="IDS_CROSTINI_REPOSITORY_SEARCH_RESULT_TITLE_PLACEHOLDER_TEXT" translateable="false" desc="Placeholder title text for surfaced Crostini Repository Search results in the app launcher">
+  <message name="IDS_CROSTINI_REPOSITORY_SEARCH_RESULT_PLACEHOLDER_TEXT" translateable="false" desc="Placeholder text for surfaced Crostini Repository Search results in the app launcher">
     Install <ph name="LINUX_APP_NAME">$1<ex>GIMP</ex></ph>
   </message>
-  <message name="IDS_CROSTINI_REPOSITORY_SEARCH_RESULT_DETAILS_PLACEHOLDER_TEXT" translateable="false" desc="Placeholder description details for surfaced Crostini Repository Search results in the app launcher">
-    Crostini Application
-  </message>
 
   <!-- Time limit notification -->
   <message name="IDS_SCREEN_TIME_NOTIFICATION_TITLE" desc="The title of the notification when screen usage limit reaches before locking the device.">
diff --git a/chrome/app/file_manager_strings.grdp b/chrome/app/file_manager_strings.grdp
index 8fb74f4..d1a3cd2a 100644
--- a/chrome/app/file_manager_strings.grdp
+++ b/chrome/app/file_manager_strings.grdp
@@ -245,6 +245,9 @@
   <message name="IDS_FILE_BROWSER_CLOSE_VOLUME_BUTTON_LABEL" desc="Title of the action for closing either an archive volume or a volume provided by an extension.">
     Close
   </message>
+  <message name="IDS_FILE_BROWSER_SEND_FEEDBACK_BUTTON_LABEL" desc="Title for the action of sending user feedback.">
+    Send feedback
+  </message>
   <message name="IDS_FILE_BROWSER_ADD_NEW_SERVICES_BUTTON_LABEL" desc="Title of the button in the left nav to add new services (file systems) to the Files app.">
     Add new service
   </message>
diff --git a/chrome/app/file_manager_strings_grdp/IDS_FILE_BROWSER_SEND_FEEDBACK_BUTTON_LABEL.png.sha1 b/chrome/app/file_manager_strings_grdp/IDS_FILE_BROWSER_SEND_FEEDBACK_BUTTON_LABEL.png.sha1
new file mode 100644
index 0000000..9d37f3e
--- /dev/null
+++ b/chrome/app/file_manager_strings_grdp/IDS_FILE_BROWSER_SEND_FEEDBACK_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@
+8aeefd746445416a2493a2142702dda65ddf1bf0
\ No newline at end of file
diff --git a/chrome/app/profiles_strings.grdp b/chrome/app/profiles_strings.grdp
index 914e9ac..52f9327 100644
--- a/chrome/app/profiles_strings.grdp
+++ b/chrome/app/profiles_strings.grdp
@@ -17,6 +17,9 @@
   <message name="IDS_GENERIC_USER_AVATAR_LABEL" desc="Label shown for the user that is currently active, when there are multiple user accounts.">
     Current user
   </message>
+  <message name="IDS_AVATAR_BUTTON_INCOGNITO" desc="Short label for the avatar button when the user is in incognito mode." meaning="This window is browsing in incognito mode.">
+    Incognito
+  </message>
   <message name="IDS_AVATAR_BUTTON_INCOGNITO_TOOLTIP" desc="Tooltip for the inactive avatar button when the user is in incognito mode.">
     You're incognito
   </message>
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index e23b673..bffa23b 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5400,8 +5400,6 @@
     "search_engines/template_url_service_test_util.h",
     "signin/fake_account_fetcher_service_builder.cc",
     "signin/fake_account_fetcher_service_builder.h",
-    "signin/fake_profile_oauth2_token_service_builder.cc",
-    "signin/fake_profile_oauth2_token_service_builder.h",
     "signin/gaia_cookie_manager_service_test_util.cc",
     "signin/gaia_cookie_manager_service_test_util.h",
     "signin/identity_test_environment_profile_adaptor.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 59d4948..53cb707 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4298,6 +4298,10 @@
          autofill_assistant::features::kAutofillAssistantChromeEntry)},
 #endif  // defined(OS_ANDROID)
 
+    {"disable-best-effort-tasks",
+     flag_descriptions::kDisableBestEffortTasksName,
+     flag_descriptions::kDisableBestEffortTasksDescription, kOsAll,
+     SINGLE_VALUE_TYPE(switches::kDisableBestEffortTasks)},
     {"enable-sync-uss-passwords",
      flag_descriptions::kEnableSyncUSSPasswordsName,
      flag_descriptions::kEnableSyncUSSPasswordsDescription,
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 4d69563..2aa0fdb 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3954,9 +3954,9 @@
   return std::vector<service_manager::Manifest> {
     GetChromeRendererManifest(),
 #if BUILDFLAG(ENABLE_NACL)
-        nacl_loader::GetManifest(),
+        GetNaClLoaderManifest(),
 #if defined(OS_WIN) && defined(ARCH_CPU_X86)
-        nacl_broker::GetManifest(),
+        GetNaClBrokerManifest(),
 #endif  // defined(OS_WIN)
 #endif  // BUILDFLAG(ENABLE_NACL)
   };
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
index 5515b8c1..92965882 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.cc
@@ -42,7 +42,6 @@
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/storage_partition.h"
-#include "services/identity/public/cpp/identity_manager.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 
 namespace arc {
@@ -65,7 +64,7 @@
  private:
   friend struct base::DefaultSingletonTraits<ArcAuthServiceFactory>;
 
-  ArcAuthServiceFactory() = default;
+  ArcAuthServiceFactory() { DependsOn(IdentityManagerFactory::GetInstance()); }
   ~ArcAuthServiceFactory() override = default;
 };
 
@@ -161,15 +160,29 @@
 }
 
 std::string GetGaiaIdFromAccountName(
-    const AccountTrackerService* account_tracker_service,
+    const identity::IdentityManager* identity_manager,
     const std::string& account_name) {
   std::string gaia_id =
-      account_tracker_service->FindAccountInfoByEmail(account_name).gaia;
+      identity_manager
+          ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(
+              account_name)
+          ->gaia;
   DCHECK(!gaia_id.empty());
 
   return gaia_id;
 }
 
+chromeos::AccountManager* GetAccountManagerForProfile(Profile* profile) {
+  if (!chromeos::switches::IsAccountManagerEnabled())
+    return nullptr;
+
+  // TODO(sinhak): This will need to be independent of Profile, when
+  // Multi-Profile on Chrome OS is launched.
+  auto* factory =
+      g_browser_process->platform_part()->GetAccountManagerFactory();
+  return factory->GetAccountManager(profile->GetPath().value());
+}
+
 }  // namespace
 
 // static
@@ -184,6 +197,7 @@
 ArcAuthService::ArcAuthService(content::BrowserContext* browser_context,
                                ArcBridgeService* arc_bridge_service)
     : profile_(Profile::FromBrowserContext(browser_context)),
+      account_manager_(GetAccountManagerForProfile(profile_)),
       account_tracker_service_(
           AccountTrackerServiceFactory::GetInstance()->GetForProfile(profile_)),
       identity_manager_(IdentityManagerFactory::GetForProfile(profile_)),
@@ -197,29 +211,15 @@
   arc_bridge_service_->auth()->AddObserver(this);
 
   ArcSessionManager::Get()->AddObserver(this);
-
-  // |ArcAuthService| needs to listen on |AccountTrackerService| for account
-  // removals (See crbug.com/904978) and |AccountManager| for account updates
-  // (|ArcAuthService| cannot rely on |AccountTrackerService| for account
-  // updates because |AccountTrackerService| does not notify its observers when
-  // an account's LST changes).
-  account_tracker_service_->AddObserver(this);
-
-  if (chromeos::switches::IsAccountManagerEnabled()) {
-    // TODO(sinhak): This will need to be independent of Profile, when
-    // Multi-Profile on Chrome OS is launched.
-    chromeos::AccountManagerFactory* factory =
-        g_browser_process->platform_part()->GetAccountManagerFactory();
-    account_manager_ = factory->GetAccountManager(profile_->GetPath().value());
+  identity_manager_->AddObserver(this);
+  if (account_manager_)
     account_manager_->AddObserver(this);
-  }
 }
 
 ArcAuthService::~ArcAuthService() {
-  if (chromeos::switches::IsAccountManagerEnabled())
+  if (account_manager_)
     account_manager_->RemoveObserver(this);
 
-  account_tracker_service_->RemoveObserver(this);
   ArcSessionManager::Get()->RemoveObserver(this);
   arc_bridge_service_->auth()->RemoveObserver(this);
   arc_bridge_service_->auth()->SetHost(nullptr);
@@ -278,8 +278,7 @@
 
   if (!account_name.has_value() ||
       IsPrimaryAccount(chromeos::AccountManager::AccountKey{
-          GetGaiaIdFromAccountName(account_tracker_service_,
-                                   account_name.value()),
+          GetGaiaIdFromAccountName(identity_manager_, account_name.value()),
           chromeos::account_manager::AccountType::ACCOUNT_TYPE_GAIA})) {
     // Reauthorization for the Primary Account.
     // The check for |!account_name.has_value()| is for backwards compatibility
@@ -396,7 +395,7 @@
 
   // Check if |account_name| points to a Secondary Account.
   if (!IsPrimaryAccount(chromeos::AccountManager::AccountKey{
-          GetGaiaIdFromAccountName(account_tracker_service_, account_name),
+          GetGaiaIdFromAccountName(identity_manager_, account_name),
           chromeos::account_manager::AccountType::ACCOUNT_TYPE_GAIA})) {
     FetchSecondaryAccountInfo(account_name, std::move(callback));
     return;
@@ -525,7 +524,7 @@
   // notifications. See crbug.com/904978.
 }
 
-void ArcAuthService::OnAccountRemoved(const AccountInfo& account_info) {
+void ArcAuthService::OnAccountRemovedWithInfo(const AccountInfo& account_info) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
   if (!chromeos::switches::IsAccountManagerEnabled())
@@ -554,6 +553,10 @@
   TriggerAccountsPushToArc();
 }
 
+void ArcAuthService::Shutdown() {
+  identity_manager_->RemoveObserver(this);
+}
+
 void ArcAuthService::OnActiveDirectoryEnrollmentTokenFetched(
     ArcActiveDirectoryEnrollmentTokenFetcher* fetcher,
     RequestPrimaryAccountInfoCallback callback,
@@ -632,8 +635,13 @@
     RequestAccountInfoCallback callback) {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
 
-  const std::string account_id =
-      account_tracker_service_->FindAccountInfoByEmail(account_name).account_id;
+  base::Optional<AccountInfo> account_info =
+      identity_manager_
+          ->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(
+              account_name);
+  DCHECK(account_info.has_value());
+
+  const std::string& account_id = account_info->account_id;
   DCHECK(!account_id.empty());
 
   std::unique_ptr<ArcBackgroundAuthCodeFetcher> fetcher =
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service.h b/chrome/browser/chromeos/arc/auth/arc_auth_service.h
index 293600f..c264f52 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service.h
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service.h
@@ -21,7 +21,7 @@
 #include "components/arc/common/auth.mojom.h"
 #include "components/arc/connection_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
-#include "components/signin/core/browser/account_tracker_service.h"
+#include "services/identity/public/cpp/identity_manager.h"
 
 class Profile;
 
@@ -49,7 +49,7 @@
                        public mojom::AuthHost,
                        public ConnectionObserver<mojom::AuthInstance>,
                        public chromeos::AccountManager::Observer,
-                       public AccountTrackerService::Observer,
+                       public identity::IdentityManager::Observer,
                        public ArcSessionManager::Observer {
  public:
   using GetGoogleAccountsInArcCallback =
@@ -101,12 +101,15 @@
   void OnAccountRemoved(
       const chromeos::AccountManager::AccountKey& account_key) override;
 
-  // AccountTrackerService::Observer:
-  void OnAccountRemoved(const AccountInfo& account_info) override;
+  // IdentityManager::Observer:
+  void OnAccountRemovedWithInfo(const AccountInfo& account_info) override;
 
   // ArcSessionManager::Observer:
   void OnArcInitialStart() override;
 
+  // KeyedService:
+  void Shutdown() override;
+
   void SkipMergeSessionForTesting();
 
  private:
@@ -193,7 +196,7 @@
 
   // Non-owning pointers.
   Profile* const profile_;
-  chromeos::AccountManager* account_manager_ = nullptr;
+  chromeos::AccountManager* const account_manager_;
   AccountTrackerService* const account_tracker_service_;
   identity::IdentityManager* const identity_manager_;
   ArcBridgeService* const arc_bridge_service_;
diff --git a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
index 3968fa4..c9b7560 100644
--- a/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
+++ b/chrome/browser/chromeos/arc/auth/arc_auth_service_browsertest.cc
@@ -30,7 +30,7 @@
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/account_tracker_service_factory.h"
+#include "chrome/browser/signin/account_fetcher_service_factory.h"
 #include "chrome/browser/signin/chrome_device_id_helper.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
@@ -59,10 +59,12 @@
 #include "components/policy/core/common/policy_switches.h"
 #include "components/prefs/pref_member.h"
 #include "components/prefs/pref_service.h"
+#include "components/signin/core/browser/account_fetcher_service.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/user_manager.h"
 #include "components/user_manager/user_names.h"
 #include "content/public/browser/browser_task_traits.h"
+#include "services/identity/public/cpp/accounts_mutator.h"
 #include "services/identity/public/cpp/identity_manager.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
@@ -630,9 +632,15 @@
       identity_manager->FindAccountInfoForAccountWithRefreshTokenByEmailAddress(
           kSecondaryAccountEmail);
   ASSERT_TRUE(maybe_account_info.has_value());
-  AccountTrackerService* account_tracker_service =
-      AccountTrackerServiceFactory::GetInstance()->GetForProfile(profile());
-  account_tracker_service->RemoveAccount(maybe_account_info.value().account_id);
+
+  AccountFetcherService* account_fetcher_service =
+      AccountFetcherServiceFactory::GetForProfile(profile());
+  // Necessary to ensure that the OnAccountRemovedWithInfo() observer will be
+  // sent.
+  account_fetcher_service->EnableNetworkFetchesForTest();
+  identity_manager->GetAccountsMutator()->RemoveAccount(
+      maybe_account_info.value().account_id,
+      signin_metrics::SourceForRefreshTokenOperation::kUnknown);
   base::RunLoop().RunUntilIdle();
 
   EXPECT_EQ(1, auth_instance().num_account_removed_calls());
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.cc b/chrome/browser/chromeos/crostini/crostini_manager.cc
index f3ef91e..1cddd80 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager.cc
@@ -517,7 +517,6 @@
 }
 
 LinuxPackageInfo::LinuxPackageInfo() = default;
-LinuxPackageInfo::LinuxPackageInfo(const LinuxPackageInfo&) = default;
 LinuxPackageInfo::~LinuxPackageInfo() = default;
 
 ContainerInfo::ContainerInfo(std::string container_name,
@@ -1163,23 +1162,6 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
-void CrostiniManager::GetLinuxPackageInfoFromApt(
-    const std::string& vm_name,
-    const std::string& container_name,
-    const std::string& package_name,
-    GetLinuxPackageInfoCallback callback) {
-  vm_tools::cicerone::LinuxPackageInfoFromAptRequest request;
-  request.set_owner_id(owner_id_);
-  request.set_vm_name(vm_name);
-  request.set_container_name(container_name);
-  request.set_package_name(package_name);
-
-  GetCiceroneClient()->GetLinuxPackageInfoFromApt(
-      std::move(request),
-      base::BindOnce(&CrostiniManager::OnGetLinuxPackageInfo,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
 void CrostiniManager::InstallLinuxPackage(
     std::string vm_name,
     std::string container_name,
@@ -1206,32 +1188,6 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
 }
 
-void CrostiniManager::InstallLinuxPackageFromApt(
-    const std::string& vm_name,
-    const std::string& container_name,
-    const std::string& package_id,
-    InstallLinuxPackageCallback callback) {
-  if (!GetCiceroneClient()->IsInstallLinuxPackageProgressSignalConnected()) {
-    // Technically we could still start the install, but we wouldn't be able to
-    // detect when the install completes, successfully or otherwise.
-    LOG(ERROR)
-        << "Attempted to install package when progress signal not connected.";
-    std::move(callback).Run(CrostiniResult::INSTALL_LINUX_PACKAGE_FAILED);
-    return;
-  }
-
-  vm_tools::cicerone::InstallLinuxPackageFromAptRequest request;
-  request.set_owner_id(owner_id_);
-  request.set_vm_name(vm_name);
-  request.set_container_name(container_name);
-  request.set_package_id(package_id);
-
-  GetCiceroneClient()->InstallLinuxPackageFromApt(
-      std::move(request),
-      base::BindOnce(&CrostiniManager::OnInstallLinuxPackage,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-}
-
 void CrostiniManager::UninstallPackageOwningFile(
     std::string vm_name,
     std::string container_name,
@@ -2315,7 +2271,6 @@
   }
 
   result.success = true;
-  result.package_id = response.package_id();
   result.name = split[0];
   result.version = split[1];
   result.description = response.description();
diff --git a/chrome/browser/chromeos/crostini/crostini_manager.h b/chrome/browser/chromeos/crostini/crostini_manager.h
index a219cfe..28001e9 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager.h
+++ b/chrome/browser/chromeos/crostini/crostini_manager.h
@@ -125,7 +125,6 @@
 
 struct LinuxPackageInfo {
   LinuxPackageInfo();
-  LinuxPackageInfo(const LinuxPackageInfo&);
   ~LinuxPackageInfo();
 
   bool success;
@@ -134,8 +133,6 @@
   std::string failure_reason;
 
   // The remaining fields are only set when success is true.
-  // package_id is given as "name;version;arch;data".
-  std::string package_id;
   std::string name;
   std::string version;
   std::string summary;
@@ -425,13 +422,6 @@
                            std::string package_path,
                            GetLinuxPackageInfoCallback callback);
 
-  // Asynchronously retrieve information about a Linux Package in the APT
-  // repository. This uses a package_name to identify a package.
-  void GetLinuxPackageInfoFromApt(const std::string& vm_name,
-                                  const std::string& container_name,
-                                  const std::string& package_name,
-                                  GetLinuxPackageInfoCallback callback);
-
   // Begin installation of a Linux Package inside the container. If the
   // installation is successfully started, further updates will be sent to
   // added LinuxPackageOperationProgressObservers.
@@ -440,16 +430,6 @@
                            std::string package_path,
                            InstallLinuxPackageCallback callback);
 
-  // Begin installation of a Linux Package inside the container. If the
-  // installation is successfully started, further updates will be sent to
-  // added LinuxPackageOperationProgressObservers. Uses a package_id, given
-  // by "package_name;version;arch;data", to identify the package to install
-  // from the APT repository.
-  void InstallLinuxPackageFromApt(const std::string& vm_name,
-                                  const std::string& container_name,
-                                  const std::string& package_id,
-                                  InstallLinuxPackageCallback callback);
-
   // Begin uninstallation of a Linux Package inside the container. The package
   // is identified by its associated .desktop file's ID; we don't use package_id
   // to avoid problems with stale package_ids (such as after upgrades). If the
@@ -717,8 +697,7 @@
       GetContainerAppIconsCallback callback,
       base::Optional<vm_tools::cicerone::ContainerAppIconResponse> reply);
 
-  // Callback for CrostiniManager::GetLinuxPackageInfo and
-  // CrostiniManager::GetLinuxPackageInfoFromApt.
+  // Callback for CrostiniManager::GetLinuxPackageInfo.
   void OnGetLinuxPackageInfo(
       GetLinuxPackageInfoCallback callback,
       base::Optional<vm_tools::cicerone::LinuxPackageInfoResponse> reply);
diff --git a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
index 696bcb44..4f93a8a9 100644
--- a/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
+++ b/chrome/browser/chromeos/crostini/crostini_manager_unittest.cc
@@ -18,7 +18,6 @@
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "device/usb/public/cpp/fake_usb_device_manager.h"
 #include "storage/browser/fileapi/external_mount_points.h"
-#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace crostini {
@@ -26,7 +25,6 @@
 namespace {
 const char kVmName[] = "vm_name";
 const char kContainerName[] = "container_name";
-const char kPackageID[] = "package;1;;";
 constexpr int64_t kDiskSizeBytes = 4ll * 1024 * 1024 * 1024;  // 4 GiB
 }  // namespace
 
@@ -157,27 +155,6 @@
     std::move(closure).Run();
   }
 
-  void SearchAppCallback(base::OnceClosure closure,
-                         const std::vector<std::string>& expected_result,
-                         const std::vector<std::string>& result) {
-    EXPECT_THAT(result, testing::ContainerEq(expected_result));
-    std::move(closure).Run();
-  }
-
-  void GetLinuxPackageInfoFromAptCallback(
-      base::OnceClosure closure,
-      const LinuxPackageInfo& expected_result,
-      const LinuxPackageInfo& result) {
-    EXPECT_EQ(result.success, expected_result.success);
-    EXPECT_EQ(result.failure_reason, expected_result.failure_reason);
-    EXPECT_EQ(result.package_id, expected_result.package_id);
-    EXPECT_EQ(result.name, expected_result.name);
-    EXPECT_EQ(result.version, expected_result.version);
-    EXPECT_EQ(result.summary, expected_result.summary);
-    EXPECT_EQ(result.description, expected_result.description);
-    std::move(closure).Run();
-  }
-
   CrostiniManagerTest()
       : test_browser_thread_bundle_(
             content::TestBrowserThreadBundle::REAL_IO_THREAD) {
@@ -1021,142 +998,6 @@
   EXPECT_FALSE(crostini_manager()->GetContainerInfo(kVmName, kContainerName));
 }
 
-TEST_F(CrostiniManagerTest, InstallLinuxPackageFromAptSignalNotConnectedError) {
-  fake_cicerone_client_->set_install_linux_package_progress_signal_connected(
-      false);
-  crostini_manager()->InstallLinuxPackageFromApt(
-      kVmName, kContainerName, kPackageID,
-      base::BindOnce(&CrostiniManagerTest::CrostiniResultCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     CrostiniResult::INSTALL_LINUX_PACKAGE_FAILED));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, InstallLinuxPackageFromAptSignalSuccess) {
-  vm_tools::cicerone::InstallLinuxPackageResponse response;
-  response.set_status(vm_tools::cicerone::InstallLinuxPackageResponse::STARTED);
-  fake_cicerone_client_->set_install_linux_package_response(response);
-  crostini_manager()->InstallLinuxPackageFromApt(
-      kVmName, kContainerName, kPackageID,
-      base::BindOnce(&CrostiniManagerTest::CrostiniResultCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     CrostiniResult::SUCCESS));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, InstallLinuxPackageFromAptSignalFailure) {
-  vm_tools::cicerone::InstallLinuxPackageResponse response;
-  response.set_status(vm_tools::cicerone::InstallLinuxPackageResponse::FAILED);
-  response.set_failure_reason(
-      "Unit tests can't install Linux package from apt!");
-  fake_cicerone_client_->set_install_linux_package_response(response);
-  crostini_manager()->InstallLinuxPackageFromApt(
-      kVmName, kContainerName, kPackageID,
-      base::BindOnce(&CrostiniManagerTest::CrostiniResultCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     CrostiniResult::INSTALL_LINUX_PACKAGE_FAILED));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, InstallLinuxPackageFromAptSignalOperationBlocked) {
-  vm_tools::cicerone::InstallLinuxPackageResponse response;
-  response.set_status(
-      vm_tools::cicerone::InstallLinuxPackageResponse::INSTALL_ALREADY_ACTIVE);
-  fake_cicerone_client_->set_install_linux_package_response(response);
-  crostini_manager()->InstallLinuxPackageFromApt(
-      kVmName, kContainerName, kPackageID,
-      base::BindOnce(&CrostiniManagerTest::CrostiniResultCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     CrostiniResult::BLOCKING_OPERATION_ALREADY_ACTIVE));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, SearchAppSuccess) {
-  vm_tools::cicerone::AppSearchResponse response;
-  vm_tools::cicerone::AppSearchResponse::AppSearchResult* app =
-      response.add_packages();
-  app->set_package_name("fake app");
-  app = response.add_packages();
-  app->set_package_name("fake app1");
-  app = response.add_packages();
-  app->set_package_name("fake app2");
-  fake_cicerone_client_->set_search_app_response(response);
-  std::vector<std::string> expected = {"fake app", "fake app1", "fake app2"};
-  crostini_manager()->SearchApp(
-      kVmName, kContainerName, "fake ap",
-      base::BindOnce(&CrostiniManagerTest::SearchAppCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     expected));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, SearchAppNoResults) {
-  vm_tools::cicerone::AppSearchResponse response;
-  fake_cicerone_client_->set_search_app_response(response);
-  std::vector<std::string> expected = {};
-  crostini_manager()->SearchApp(
-      kVmName, kContainerName, "fake ap",
-      base::BindOnce(&CrostiniManagerTest::SearchAppCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     expected));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, GetLinuxPackageInfoFromAptFailedToGetInfo) {
-  const char kFailMessage[] = "Failed to get package info.";
-  vm_tools::cicerone::LinuxPackageInfoResponse response;
-  response.set_success(false);
-  response.set_failure_reason(kFailMessage);
-  fake_cicerone_client_->set_linux_package_info_response(response);
-  LinuxPackageInfo expected;
-  expected.success = false;
-  expected.failure_reason = kFailMessage;
-  crostini_manager()->GetLinuxPackageInfoFromApt(
-      kVmName, kContainerName, "fake app",
-      base::BindOnce(&CrostiniManagerTest::GetLinuxPackageInfoFromAptCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     expected));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, GetLinuxPackageInfoFromAptInvalidID) {
-  vm_tools::cicerone::LinuxPackageInfoResponse response;
-  response.set_success(true);
-  response.set_package_id("Bad;;id;");
-  fake_cicerone_client_->set_linux_package_info_response(response);
-  LinuxPackageInfo expected;
-  expected.success = false;
-  expected.failure_reason = "Linux package info contained invalid package id.";
-  crostini_manager()->GetLinuxPackageInfoFromApt(
-      kVmName, kContainerName, "fake app",
-      base::BindOnce(&CrostiniManagerTest::GetLinuxPackageInfoFromAptCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     expected));
-  run_loop()->Run();
-}
-
-TEST_F(CrostiniManagerTest, GetLinuxPackageInfoFromAptSuccess) {
-  vm_tools::cicerone::LinuxPackageInfoResponse response;
-  response.set_success(true);
-  response.set_package_id("good;1.1;id;");
-  response.set_summary("A summary");
-  response.set_description("A description");
-  fake_cicerone_client_->set_linux_package_info_response(response);
-  LinuxPackageInfo expected;
-  expected.success = true;
-  expected.package_id = "good;1.1;id;";
-  expected.name = "good";
-  expected.version = "1.1";
-  expected.summary = "A summary";
-  expected.description = "A description";
-  crostini_manager()->GetLinuxPackageInfoFromApt(
-      kVmName, kContainerName, "fake app",
-      base::BindOnce(&CrostiniManagerTest::GetLinuxPackageInfoFromAptCallback,
-                     base::Unretained(this), run_loop()->QuitClosure(),
-                     expected));
-  run_loop()->Run();
-}
-
 TEST_F(CrostiniManagerRestartTest, RestartThenUninstall) {
   restart_id_ = crostini_manager()->RestartCrostini(
       kVmName, kContainerName,
diff --git a/chrome/browser/chromeos/crostini/crostini_package_service.cc b/chrome/browser/chromeos/crostini/crostini_package_service.cc
index 153f7cb..c9ca0c63 100644
--- a/chrome/browser/chromeos/crostini/crostini_package_service.cc
+++ b/chrome/browser/chromeos/crostini/crostini_package_service.cc
@@ -154,18 +154,6 @@
                      std::move(callback)));
 }
 
-void CrostiniPackageService::InstallLinuxPackageFromApt(
-    const std::string& vm_name,
-    const std::string& container_name,
-    const std::string& package_id,
-    CrostiniManager::InstallLinuxPackageCallback callback) {
-  CrostiniManager::GetForProfile(profile_)->InstallLinuxPackageFromApt(
-      vm_name, container_name, package_id,
-      base::BindOnce(&CrostiniPackageService::OnInstallLinuxPackage,
-                     weak_ptr_factory_.GetWeakPtr(), vm_name, container_name,
-                     std::move(callback)));
-}
-
 void CrostiniPackageService::OnInstallLinuxPackageProgress(
     const std::string& vm_name,
     const std::string& container_name,
diff --git a/chrome/browser/chromeos/crostini/crostini_package_service.h b/chrome/browser/chromeos/crostini/crostini_package_service.h
index ef64f2e..749e5ad 100644
--- a/chrome/browser/chromeos/crostini/crostini_package_service.h
+++ b/chrome/browser/chromeos/crostini/crostini_package_service.h
@@ -51,14 +51,6 @@
       const std::string& package_path,
       CrostiniManager::InstallLinuxPackageCallback callback);
 
-  // Install a Linux package via a package_id. If successfully started, a
-  // system notification will be used to display further updates.
-  void InstallLinuxPackageFromApt(
-      const std::string& vm_name,
-      const std::string& container_name,
-      const std::string& package_id,
-      CrostiniManager::InstallLinuxPackageCallback callback);
-
   // LinuxPackageOperationProgressObserver:
   void OnInstallLinuxPackageProgress(const std::string& vm_name,
                                      const std::string& container_name,
diff --git a/chrome/browser/chromeos/crostini/crostini_util.cc b/chrome/browser/chromeos/crostini/crostini_util.cc
index fbe2c59..ba442527 100644
--- a/chrome/browser/chromeos/crostini/crostini_util.cc
+++ b/chrome/browser/chromeos/crostini/crostini_util.cc
@@ -16,7 +16,6 @@
 #include "base/timer/timer.h"
 #include "chrome/browser/chromeos/crostini/crostini_app_launch_observer.h"
 #include "chrome/browser/chromeos/crostini/crostini_manager.h"
-#include "chrome/browser/chromeos/crostini/crostini_package_service.h"
 #include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
 #include "chrome/browser/chromeos/crostini/crostini_registry_service.h"
 #include "chrome/browser/chromeos/crostini/crostini_registry_service_factory.h"
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
index c2b6027..51a4c94b 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest.cc
@@ -6,12 +6,10 @@
 
 #include "base/stl_util.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/threading/thread_restrictions.h"
 #include "chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h"
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
-#include "chrome/common/chrome_features.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/user_manager/user_manager.h"
@@ -67,6 +65,11 @@
     return *this;
   }
 
+  TestCase& DisableNativeSmb() {
+    enable_native_smb = false;
+    return *this;
+  }
+
   TestCase& DontMountVolumes() {
     mount_no_volumes = true;
     return *this;
@@ -99,6 +102,9 @@
     if (test.enable_drivefs.value_or(false))
       name.append("_DriveFs");
 
+    if (!test.enable_native_smb)
+      name.append("_DisableNativeSmb");
+
     if (test.enable_myfiles_volume.value_or(false))
       name.append("_MyFilesVolume");
 
@@ -114,6 +120,7 @@
   bool with_browser = false;
   bool needs_zip = false;
   bool offline = false;
+  bool enable_native_smb = true;
   bool mount_no_volumes = false;
 };
 
@@ -188,12 +195,15 @@
 
   bool GetIsOffline() const override { return GetParam().offline; }
 
+  bool GetEnableNativeSmb() const override {
+    return GetParam().enable_native_smb;
+  }
+
   bool GetStartWithNoVolumesMounted() const override {
     return GetParam().mount_no_volumes;
   }
 
  private:
-  base::test::ScopedFeatureList scoped_feature_list_;
   DISALLOW_COPY_AND_ASSIGN(FilesAppBrowserTest);
 };
 
@@ -843,10 +853,15 @@
     Providers, /* providers.js */
     FilesAppBrowserTest,
     ::testing::Values(TestCase("requestMount"),
+                      TestCase("requestMount").DisableNativeSmb(),
                       TestCase("requestMountMultipleMounts"),
+                      TestCase("requestMountMultipleMounts").DisableNativeSmb(),
                       TestCase("requestMountSourceDevice"),
+                      TestCase("requestMountSourceDevice").DisableNativeSmb(),
                       TestCase("requestMountSourceFile"),
-                      TestCase("providerEject")));
+                      TestCase("requestMountSourceFile").DisableNativeSmb(),
+                      TestCase("providerEject"),
+                      TestCase("providerEject").DisableNativeSmb()));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
     GearMenu, /* gear_menu.js */
@@ -861,7 +876,8 @@
         TestCase("showToggleHiddenAndroidFoldersGearMenuItemsInMyFiles"),
         TestCase("enableToggleHiddenAndroidFoldersShowsHiddenFiles"),
         TestCase("hideCurrentDirectoryByTogglingHiddenAndroidFolders"),
-        TestCase("newFolderInDownloads")));
+        TestCase("newFolderInDownloads"),
+        TestCase("showSendFeedbackAction")));
 
 WRAPPED_INSTANTIATE_TEST_CASE_P(
     Crostini, /* crostini.js */
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
index d270402..96a1e2a 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.cc
@@ -1269,10 +1269,16 @@
 
   std::vector<base::Feature> enabled_features;
   std::vector<base::Feature> disabled_features;
+
   if (!IsGuestModeTest()) {
     enabled_features.emplace_back(features::kCrostini);
     enabled_features.emplace_back(chromeos::features::kCrostiniFiles);
   }
+
+  if (!IsNativeSmbTest()) {
+    disabled_features.emplace_back(features::kNativeSmb);
+  }
+
   if (IsDriveFsTest()) {
     enabled_features.emplace_back(chromeos::features::kDriveFs);
   } else {
@@ -1416,6 +1422,10 @@
   return false;
 }
 
+bool FileManagerBrowserTestBase::GetEnableNativeSmb() const {
+  return true;
+}
+
 bool FileManagerBrowserTestBase::GetStartWithNoVolumesMounted() const {
   return false;
 }
@@ -1837,7 +1847,7 @@
   }
 
   if (name == "isSmbEnabled") {
-    *output = IsSmbEnabled() ? "true" : "false";
+    *output = IsNativeSmbTest() ? "true" : "false";
     return;
   }
 
@@ -1894,8 +1904,4 @@
   waiter.EnableVirtualKeyboard();
 }
 
-bool FileManagerBrowserTestBase::IsSmbEnabled() const {
-  return base::FeatureList::IsEnabled(features::kNativeSmb);
-}
-
 }  // namespace file_manager
diff --git a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h
index 92b9c0951..3534e47 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h
+++ b/chrome/browser/chromeos/file_manager/file_manager_browsertest_base.h
@@ -54,6 +54,7 @@
   virtual bool GetRequiresStartupBrowser() const;
   virtual bool GetNeedsZipSupport() const;
   virtual bool GetIsOffline() const;
+  virtual bool GetEnableNativeSmb() const;
   virtual bool GetStartWithNoVolumesMounted() const;
 
   // Launches the test extension from GetTestExtensionManifestName() and uses
@@ -83,6 +84,10 @@
   // Returns true if Drive should act as if offline.
   bool IsOfflineTest() const { return GetIsOffline(); }
 
+  // Returns true if the test needs a native SMB file system provider.
+  bool IsNativeSmbTest() const { return GetEnableNativeSmb(); }
+
+  // Returns true if FilesApp should start with no volumes mounted.
   bool DoesTestStartWithNoVolumesMounted() const {
     return GetStartWithNoVolumesMounted();
   }
diff --git a/chrome/browser/chromeos/file_manager/file_manager_string_util.cc b/chrome/browser/chromeos/file_manager/file_manager_string_util.cc
index 24e63e6..89361fb 100644
--- a/chrome/browser/chromeos/file_manager/file_manager_string_util.cc
+++ b/chrome/browser/chromeos/file_manager/file_manager_string_util.cc
@@ -671,6 +671,7 @@
              IDS_FILE_BROWSER_ADD_TO_VERB_BUTTON_LABEL);
   SET_STRING("PACK_WITH_VERB_BUTTON_LABEL",
              IDS_FILE_BROWSER_PACK_WITH_VERB_BUTTON_LABEL);
+  SET_STRING("SEND_FEEDBACK", IDS_FILE_BROWSER_SEND_FEEDBACK_BUTTON_LABEL);
   SET_STRING("SHARE_WITH_VERB_BUTTON_LABEL",
              IDS_FILE_BROWSER_SHARE_WITH_VERB_BUTTON_LABEL);
   SET_STRING("PASTE_BUTTON_LABEL", IDS_FILE_BROWSER_PASTE_BUTTON_LABEL);
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_session.cc b/chrome/browser/chromeos/login/demo_mode/demo_session.cc
index 81923ece..4f54369 100644
--- a/chrome/browser/chromeos/login/demo_mode/demo_session.cc
+++ b/chrome/browser/chromeos/login/demo_mode/demo_session.cc
@@ -29,6 +29,7 @@
 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/ash/system_tray_client.h"
+#include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "chrome/browser/ui/extensions/app_launch_params.h"
 #include "chrome/browser/ui/extensions/application_launch.h"
 #include "chrome/common/extensions/extension_constants.h"
@@ -64,6 +65,11 @@
 // contains sample photos.
 constexpr char kPhotosPath[] = "media/photos";
 
+// The absolute path of the splash image that covers the login screen.
+// TODO(crbug.com/894270): Replace this placeholder image.
+constexpr char kSplashImagePath[] =
+    "/usr/share/chromeos-assets/wallpaper/guest_large.jpg";
+
 bool IsDemoModeOfflineEnrolled() {
   DCHECK(DemoSession::IsDeviceInDemoMode());
   return DemoSession::GetDemoConfig() == DemoSession::DemoModeConfig::kOffline;
@@ -435,26 +441,38 @@
 }
 
 void DemoSession::OnSessionStateChanged() {
-  if (session_manager::SessionManager::Get()->session_state() !=
-      session_manager::SessionState::ACTIVE) {
-    return;
-  }
-  // SystemTrayClient may not exist in unit tests.
-  if (SystemTrayClient::Get() &&
-      base::FeatureList::IsEnabled(switches::kShowLanguageToggleInDemoMode)) {
-    const std::string current_locale_iso_code =
-        ProfileManager::GetActiveUserProfile()->GetPrefs()->GetString(
-            language::prefs::kApplicationLocale);
-    SystemTrayClient::Get()->SetLocaleList(GetSupportedLocales(),
-                                           current_locale_iso_code);
-  }
-  RestoreDefaultLocaleForNextSession();
+  switch (session_manager::SessionManager::Get()->session_state()) {
+    case session_manager::SessionState::LOGIN_PRIMARY:
+      if (base::FeatureList::IsEnabled(switches::kShowSplashScreenInDemoMode)) {
+        WallpaperControllerClient::Get()->ShowAlwaysOnTopWallpaper(
+            base::FilePath(kSplashImagePath));
+      }
+      break;
+    case session_manager::SessionState::ACTIVE:
+      if (base::FeatureList::IsEnabled(switches::kShowSplashScreenInDemoMode))
+        WallpaperControllerClient::Get()->RemoveAlwaysOnTopWallpaper();
 
-  if (!offline_enrolled_)
-    InstallAppFromUpdateUrl(GetHighlightsAppId());
+      // SystemTrayClient may not exist in unit tests.
+      if (SystemTrayClient::Get() &&
+          base::FeatureList::IsEnabled(
+              switches::kShowLanguageToggleInDemoMode)) {
+        const std::string current_locale_iso_code =
+            ProfileManager::GetActiveUserProfile()->GetPrefs()->GetString(
+                language::prefs::kApplicationLocale);
+        SystemTrayClient::Get()->SetLocaleList(GetSupportedLocales(),
+                                               current_locale_iso_code);
+      }
+      RestoreDefaultLocaleForNextSession();
 
-  EnsureOfflineResourcesLoaded(base::BindOnce(
-      &DemoSession::InstallDemoResources, weak_ptr_factory_.GetWeakPtr()));
+      if (!offline_enrolled_)
+        InstallAppFromUpdateUrl(GetHighlightsAppId());
+
+      EnsureOfflineResourcesLoaded(base::BindOnce(
+          &DemoSession::InstallDemoResources, weak_ptr_factory_.GetWeakPtr()));
+      break;
+    default:
+      break;
+  }
 }
 
 void DemoSession::OnExtensionInstalled(content::BrowserContext* browser_context,
diff --git a/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc b/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc
index 3f9c7d0c..1fa043c 100644
--- a/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc
+++ b/chrome/browser/chromeos/login/demo_mode/demo_session_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/macros.h"
 #include "base/optional.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
 #include "chrome/browser/chromeos/login/demo_mode/demo_resources.h"
@@ -22,12 +23,15 @@
 #include "chrome/browser/chromeos/profiles/profile_helper.h"
 #include "chrome/browser/component_updater/fake_cros_component_manager.h"
 #include "chrome/browser/prefs/browser_prefs.h"
+#include "chrome/browser/ui/ash/test_wallpaper_controller.h"
+#include "chrome/browser/ui/ash/wallpaper_controller_client.h"
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/constants/chromeos_switches.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "components/language/core/browser/pref_names.h"
 #include "components/session_manager/core/session_manager.h"
@@ -55,27 +59,39 @@
 class DemoSessionTest : public testing::Test {
  public:
   DemoSessionTest()
-      : browser_process_platform_part_test_api_(
+      : profile_manager_(std::make_unique<TestingProfileManager>(
+            TestingBrowserProcess::GetGlobal())),
+        browser_process_platform_part_test_api_(
             g_browser_process->platform_part()),
         scoped_user_manager_(std::make_unique<FakeChromeUserManager>()) {}
 
   ~DemoSessionTest() override = default;
 
   void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(
+        chromeos::switches::kShowSplashScreenInDemoMode);
+
+    ASSERT_TRUE(profile_manager_->SetUp());
     chromeos::DBusThreadManager::Initialize();
     DemoSession::SetDemoConfigForTesting(DemoSession::DemoModeConfig::kOnline);
     InitializeCrosComponentManager();
     session_manager_ = std::make_unique<session_manager::SessionManager>();
+    wallpaper_controller_client_ =
+        std::make_unique<WallpaperControllerClient>();
+    wallpaper_controller_client_->InitForTesting(
+        test_wallpaper_controller_.CreateInterfacePtr());
   }
 
   void TearDown() override {
     DemoSession::ShutDownIfInitialized();
     DemoSession::ResetDemoConfigForTesting();
 
+    wallpaper_controller_client_.reset();
     chromeos::DBusThreadManager::Shutdown();
 
     cros_component_manager_ = nullptr;
     browser_process_platform_part_test_api_.ShutdownCrosComponentManager();
+    profile_manager_->DeleteAllTestingProfiles();
   }
 
  protected:
@@ -104,13 +120,42 @@
         std::move(fake_cros_component_manager));
   }
 
+  // Creates a dummy demo user with a testing profile and logs in.
+  TestingProfile* LoginDemoUser() {
+    const AccountId account_id(
+        AccountId::FromUserEmailGaiaId("demo@test.com", "demo_user"));
+    FakeChromeUserManager* user_manager =
+        static_cast<FakeChromeUserManager*>(user_manager::UserManager::Get());
+    const user_manager::User* user =
+        user_manager->AddPublicAccountUser(account_id);
+
+    auto prefs =
+        std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
+    RegisterUserProfilePrefs(prefs->registry());
+    TestingProfile* profile = profile_manager_->CreateTestingProfile(
+        "test-profile", std::move(prefs), base::ASCIIToUTF16("Test profile"),
+        1 /* avatar_id */, std::string() /* supervised_user_id */,
+        TestingProfile::TestingFactories());
+    chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
+                                                                      profile);
+
+    user_manager->LoginUser(account_id);
+    profile_manager_->SetLoggedIn(true);
+    return profile;
+  }
+
   FakeCrOSComponentManager* cros_component_manager_ = nullptr;
   content::TestBrowserThreadBundle thread_bundle_;
   std::unique_ptr<session_manager::SessionManager> session_manager_;
+  std::unique_ptr<WallpaperControllerClient> wallpaper_controller_client_;
+  TestWallpaperController test_wallpaper_controller_;
+  std::unique_ptr<TestingProfileManager> profile_manager_;
 
  private:
   BrowserProcessPlatformPartTestApi browser_process_platform_part_test_api_;
   user_manager::ScopedUserManager scoped_user_manager_;
+  chromeos::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
+  base::test::ScopedFeatureList scoped_feature_list_;
 
   DISALLOW_COPY_AND_ASSIGN(DemoSessionTest);
 };
@@ -372,54 +417,28 @@
       demo_session->resources()->GetAbsolutePath(base::FilePath("foo.txt")));
 }
 
-class DemoSessionLocaleTest : public DemoSessionTest {
- public:
-  DemoSessionLocaleTest() = default;
+TEST_F(DemoSessionTest, ShowSplashScreen) {
+  DemoSession* demo_session = DemoSession::StartIfInDemoMode();
+  ASSERT_TRUE(demo_session);
 
-  ~DemoSessionLocaleTest() override = default;
+  EXPECT_EQ(0, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
+  EXPECT_EQ(0,
+            test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
+  session_manager_->SetSessionState(
+      session_manager::SessionState::LOGIN_PRIMARY);
+  wallpaper_controller_client_->FlushForTesting();
+  EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
+  EXPECT_EQ(0,
+            test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
 
-  void SetUp() override {
-    profile_manager_ = std::make_unique<TestingProfileManager>(
-        TestingBrowserProcess::GetGlobal());
-    ASSERT_TRUE(profile_manager_->SetUp());
-    DemoSessionTest::SetUp();
-  }
+  session_manager_->SetSessionState(session_manager::SessionState::ACTIVE);
+  wallpaper_controller_client_->FlushForTesting();
+  EXPECT_EQ(1, test_wallpaper_controller_.show_always_on_top_wallpaper_count());
+  EXPECT_EQ(1,
+            test_wallpaper_controller_.remove_always_on_top_wallpaper_count());
+}
 
-  void TearDown() override {
-    profile_manager_->DeleteAllTestingProfiles();
-    DemoSessionTest::TearDown();
-  }
-
- protected:
-  // Creates a dummy demo user with a testing profile and logs in.
-  TestingProfile* LoginDemoUser() {
-    const AccountId account_id(
-        AccountId::FromUserEmailGaiaId("demo@test.com", "demo_user"));
-    FakeChromeUserManager* user_manager =
-        static_cast<FakeChromeUserManager*>(user_manager::UserManager::Get());
-    const user_manager::User* user =
-        user_manager->AddPublicAccountUser(account_id);
-
-    auto prefs =
-        std::make_unique<sync_preferences::TestingPrefServiceSyncable>();
-    RegisterUserProfilePrefs(prefs->registry());
-    TestingProfile* profile = profile_manager_->CreateTestingProfile(
-        "test-profile", std::move(prefs), base::ASCIIToUTF16("Test profile"),
-        1 /* avatar_id */, std::string() /* supervised_user_id */,
-        TestingProfile::TestingFactories());
-    chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(user,
-                                                                      profile);
-
-    user_manager->LoginUser(account_id);
-    profile_manager_->SetLoggedIn(true);
-    return profile;
-  }
-
- private:
-  std::unique_ptr<TestingProfileManager> profile_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(DemoSessionLocaleTest);
-};
+using DemoSessionLocaleTest = DemoSessionTest;
 
 TEST_F(DemoSessionLocaleTest, InitializeDefaultLocale) {
   DemoSession* demo_session = DemoSession::StartIfInDemoMode();
diff --git a/chrome/browser/chromeos/network_change_manager_client.cc b/chrome/browser/chromeos/network_change_manager_client.cc
index 29de915..e8ecf645 100644
--- a/chrome/browser/chromeos/network_change_manager_client.cc
+++ b/chrome/browser/chromeos/network_change_manager_client.cc
@@ -94,10 +94,9 @@
 void NetworkChangeManagerClient::ReconnectToNetworkChangeManager() {
   ConnectToNetworkChangeManager();
 
-  // When reconnecting to the network service, tell it everything changed to
-  // make sure it refreshes itself into the correct state.
+  // Tell the restarted network service what the current connection type is.
   network_change_manager_->OnNetworkChanged(
-      /*dns_changed=*/true, /*ip_address_changed=*/true,
+      /*dns_changed=*/false, /*ip_address_changed=*/false,
       /*connection_type_changed=*/true,
       network::mojom::ConnectionType(connection_type_),
       /*connection_subtype_changed=*/true,
diff --git a/chrome/browser/chromeos/smb_client/discovery/mdns_host_locator.h b/chrome/browser/chromeos/smb_client/discovery/mdns_host_locator.h
index 1486b974..a882270 100644
--- a/chrome/browser/chromeos/smb_client/discovery/mdns_host_locator.h
+++ b/chrome/browser/chromeos/smb_client/discovery/mdns_host_locator.h
@@ -90,9 +90,9 @@
   std::vector<std::string> services_;
   HostMap results_;
 
-  std::vector<std::unique_ptr<net::MDnsTransaction>> transactions_;
-  std::unique_ptr<net::MDnsClient> mdns_client_;
   std::unique_ptr<net::MDnsSocketFactory> socket_factory_;
+  std::unique_ptr<net::MDnsClient> mdns_client_;
+  std::vector<std::unique_ptr<net::MDnsTransaction>> transactions_;
 
   DISALLOW_COPY_AND_ASSIGN(MDnsHostLocator);
 };
diff --git a/chrome/browser/devtools/BUILD.gn b/chrome/browser/devtools/BUILD.gn
index aedd2ea9..a6962666 100644
--- a/chrome/browser/devtools/BUILD.gn
+++ b/chrome/browser/devtools/BUILD.gn
@@ -15,6 +15,8 @@
   import("$_inspector_protocol/inspector_protocol.gni")
 
   _protocol_generated = [
+    "protocol/base_string_adapter.cc",
+    "protocol/base_string_adapter.h",
     "protocol/browser.cc",
     "protocol/browser.h",
     "protocol/cast.cc",
@@ -206,8 +208,6 @@
       "protocol/page_handler.h",
       "protocol/target_handler.cc",
       "protocol/target_handler.h",
-      "protocol_string.cc",
-      "protocol_string.h",
     ]
     if (is_chromeos) {
       sources += [
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
index 78756e342..0ef34b4 100644
--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
+++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.cc
@@ -102,18 +102,17 @@
 void ChromeDevToolsManagerDelegate::HandleCommand(
     DevToolsAgentHost* agent_host,
     content::DevToolsAgentHostClient* client,
-    std::unique_ptr<base::DictionaryValue> command_dict,
+    const std::string& method,
     const std::string& message,
     NotHandledCallback callback) {
   if (sessions_.find(client) == sessions_.end()) {
-    std::move(callback).Run(std::move(command_dict), message);
+    std::move(callback).Run(message);
     // This should not happen, but happens. NOTREACHED tries to get
     // a repro in some test.
     NOTREACHED();
     return;
   }
-  sessions_[client]->HandleCommand(std::move(command_dict), message,
-                                   std::move(callback));
+  sessions_[client]->HandleCommand(method, message, std::move(callback));
 }
 
 std::string ChromeDevToolsManagerDelegate::GetTargetType(
diff --git a/chrome/browser/devtools/chrome_devtools_manager_delegate.h b/chrome/browser/devtools/chrome_devtools_manager_delegate.h
index 1c50fac..27a2dd2 100644
--- a/chrome/browser/devtools/chrome_devtools_manager_delegate.h
+++ b/chrome/browser/devtools/chrome_devtools_manager_delegate.h
@@ -59,7 +59,7 @@
   void Inspect(content::DevToolsAgentHost* agent_host) override;
   void HandleCommand(content::DevToolsAgentHost* agent_host,
                      content::DevToolsAgentHostClient* client,
-                     std::unique_ptr<base::DictionaryValue> command_dict,
+                     const std::string& method,
                      const std::string& message,
                      NotHandledCallback callback) override;
   std::string GetTargetType(content::WebContents* web_contents) override;
diff --git a/chrome/browser/devtools/chrome_devtools_session.cc b/chrome/browser/devtools/chrome_devtools_session.cc
index 4ea0b58..457f578 100644
--- a/chrome/browser/devtools/chrome_devtools_session.cc
+++ b/chrome/browser/devtools/chrome_devtools_session.cc
@@ -52,30 +52,30 @@
 }
 
 void ChromeDevToolsSession::HandleCommand(
-    std::unique_ptr<base::DictionaryValue> command_dict,
+    const std::string& method,
     const std::string& message,
     content::DevToolsManagerDelegate::NotHandledCallback callback) {
-  int call_id;
-  std::string method;
-  std::unique_ptr<protocol::Value> protocolCommand =
-      protocol::toProtocolValue(command_dict.get(), 1000);
-  if (!dispatcher_->parseCommand(protocolCommand.get(), &call_id, &method))
-    return;
-  if (dispatcher_->canDispatch(method)) {
-    pending_commands_[call_id] =
-        std::make_pair(std::move(callback), std::move(command_dict));
-    dispatcher_->dispatch(call_id, method, std::move(protocolCommand), message);
+  if (!dispatcher_->canDispatch(method)) {
+    std::move(callback).Run(message);
     return;
   }
-  std::move(callback).Run(std::move(command_dict), message);
+
+  int call_id;
+  std::string unused;
+  std::unique_ptr<protocol::DictionaryValue> value =
+      protocol::DictionaryValue::cast(protocol::StringUtil::parseJSON(message));
+  if (!dispatcher_->parseCommand(value.get(), &call_id, &unused))
+    return;
+  pending_commands_[call_id] = std::move(callback);
+  dispatcher_->dispatch(call_id, method, std::move(value), message);
 }
 
 void ChromeDevToolsSession::fallThrough(int call_id,
                                         const std::string& method,
                                         const std::string& message) {
-  PendingCommand command = std::move(pending_commands_[call_id]);
+  auto callback = std::move(pending_commands_[call_id]);
   pending_commands_.erase(call_id);
-  std::move(command.first).Run(std::move(command.second), message);
+  std::move(callback).Run(message);
 }
 
 void ChromeDevToolsSession::sendProtocolNotification(
diff --git a/chrome/browser/devtools/chrome_devtools_session.h b/chrome/browser/devtools/chrome_devtools_session.h
index 5deb8af..2665df6 100644
--- a/chrome/browser/devtools/chrome_devtools_session.h
+++ b/chrome/browser/devtools/chrome_devtools_session.h
@@ -34,7 +34,7 @@
   protocol::UberDispatcher* dispatcher() { return dispatcher_.get(); }
 
   void HandleCommand(
-      std::unique_ptr<base::DictionaryValue> command_dict,
+      const std::string& method,
       const std::string& message,
       content::DevToolsManagerDelegate::NotHandledCallback callback);
 
@@ -54,10 +54,8 @@
 
   content::DevToolsAgentHost* const agent_host_;
   content::DevToolsAgentHostClient* const client_;
-  using PendingCommand =
-      std::pair<content::DevToolsManagerDelegate::NotHandledCallback,
-                std::unique_ptr<base::DictionaryValue>>;
-  base::flat_map<int, PendingCommand> pending_commands_;
+  base::flat_map<int, content::DevToolsManagerDelegate::NotHandledCallback>
+      pending_commands_;
 
   std::unique_ptr<protocol::UberDispatcher> dispatcher_;
   std::unique_ptr<BrowserHandler> browser_handler_;
diff --git a/chrome/browser/devtools/inspector_protocol_config.json b/chrome/browser/devtools/inspector_protocol_config.json
index e5838358..6e98d25 100644
--- a/chrome/browser/devtools/inspector_protocol_config.json
+++ b/chrome/browser/devtools/inspector_protocol_config.json
@@ -33,6 +33,6 @@
     "lib": {
         "package": "chrome/browser/devtools/protocol",
         "output": "protocol",
-        "string_header": "chrome/browser/devtools/protocol_string.h"
+        "string_header": "chrome/browser/devtools/protocol/base_string_adapter.h"
     }
 }
diff --git a/chrome/browser/devtools/protocol_string.cc b/chrome/browser/devtools/protocol_string.cc
deleted file mode 100644
index db3a78e..0000000
--- a/chrome/browser/devtools/protocol_string.cc
+++ /dev/null
@@ -1,205 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/devtools/protocol_string.h"
-
-#include <utility>
-#include "base/base64.h"
-#include "base/json/json_reader.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "chrome/browser/devtools/protocol/protocol.h"
-
-namespace protocol {
-
-std::unique_ptr<protocol::Value> toProtocolValue(const base::Value* value,
-                                                 int depth) {
-  if (!value || !depth)
-    return nullptr;
-  if (value->is_none())
-    return protocol::Value::null();
-  if (value->is_bool()) {
-    bool inner;
-    value->GetAsBoolean(&inner);
-    return protocol::FundamentalValue::create(inner);
-  }
-  if (value->is_int()) {
-    int inner;
-    value->GetAsInteger(&inner);
-    return protocol::FundamentalValue::create(inner);
-  }
-  if (value->is_double()) {
-    double inner;
-    value->GetAsDouble(&inner);
-    return protocol::FundamentalValue::create(inner);
-  }
-  if (value->is_string()) {
-    std::string inner;
-    value->GetAsString(&inner);
-    return protocol::StringValue::create(inner);
-  }
-  if (value->is_list()) {
-    const base::ListValue* list = nullptr;
-    value->GetAsList(&list);
-    std::unique_ptr<protocol::ListValue> result = protocol::ListValue::create();
-    for (size_t i = 0; i < list->GetSize(); i++) {
-      const base::Value* item = nullptr;
-      list->Get(i, &item);
-      std::unique_ptr<protocol::Value> converted =
-          toProtocolValue(item, depth - 1);
-      if (converted)
-        result->pushValue(std::move(converted));
-    }
-    return std::move(result);
-  }
-  if (value->is_dict()) {
-    const base::DictionaryValue* dictionary = nullptr;
-    value->GetAsDictionary(&dictionary);
-    std::unique_ptr<protocol::DictionaryValue> result =
-        protocol::DictionaryValue::create();
-    for (base::DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd();
-         it.Advance()) {
-      std::unique_ptr<protocol::Value> converted =
-          toProtocolValue(&it.value(), depth - 1);
-      if (converted)
-        result->setValue(it.key(), std::move(converted));
-    }
-    return std::move(result);
-  }
-  return nullptr;
-}
-
-std::unique_ptr<base::Value> toBaseValue(protocol::Value* value, int depth) {
-  if (!value || !depth)
-    return nullptr;
-  if (value->type() == protocol::Value::TypeNull)
-    return std::make_unique<base::Value>();
-  if (value->type() == protocol::Value::TypeBoolean) {
-    bool inner;
-    value->asBoolean(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == protocol::Value::TypeInteger) {
-    int inner;
-    value->asInteger(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == protocol::Value::TypeDouble) {
-    double inner;
-    value->asDouble(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == protocol::Value::TypeString) {
-    std::string inner;
-    value->asString(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == protocol::Value::TypeArray) {
-    protocol::ListValue* list = protocol::ListValue::cast(value);
-    std::unique_ptr<base::ListValue> result(new base::ListValue());
-    for (size_t i = 0; i < list->size(); i++) {
-      std::unique_ptr<base::Value> converted =
-          toBaseValue(list->at(i), depth - 1);
-      if (converted)
-        result->Append(std::move(converted));
-    }
-    return std::move(result);
-  }
-  if (value->type() == protocol::Value::TypeObject) {
-    protocol::DictionaryValue* dict = protocol::DictionaryValue::cast(value);
-    std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
-    for (size_t i = 0; i < dict->size(); i++) {
-      protocol::DictionaryValue::Entry entry = dict->at(i);
-      std::unique_ptr<base::Value> converted =
-          toBaseValue(entry.second, depth - 1);
-      if (converted)
-        result->SetWithoutPathExpansion(entry.first, std::move(converted));
-    }
-    return std::move(result);
-  }
-  return nullptr;
-}
-
-// static
-std::unique_ptr<protocol::Value> StringUtil::parseJSON(
-    const std::string& json) {
-  std::unique_ptr<base::Value> value = base::JSONReader::Read(json);
-  return toProtocolValue(value.get(), 1000);
-}
-
-StringBuilder::StringBuilder() {}
-
-StringBuilder::~StringBuilder() {}
-
-void StringBuilder::append(const std::string& s) {
-  string_ += s;
-}
-
-void StringBuilder::append(char c) {
-  string_ += c;
-}
-
-void StringBuilder::append(const char* characters, size_t length) {
-  string_.append(characters, length);
-}
-
-// static
-void StringUtil::builderAppendQuotedString(StringBuilder& builder,
-                                           const String& str) {
-  builder.append('"');
-  base::string16 str16 = base::UTF8ToUTF16(str);
-  escapeWideStringForJSON(reinterpret_cast<const uint16_t*>(&str16[0]),
-                          str16.length(), &builder);
-  builder.append('"');
-}
-
-std::string StringBuilder::toString() {
-  return string_;
-}
-
-void StringBuilder::reserveCapacity(size_t capacity) {
-  string_.reserve(capacity);
-}
-
-Binary::Binary() : bytes_(new base::RefCountedBytes) {}
-Binary::Binary(const Binary& binary) : bytes_(binary.bytes_) {}
-Binary::Binary(scoped_refptr<base::RefCountedMemory> bytes) : bytes_(bytes) {}
-Binary::~Binary() {}
-
-String Binary::toBase64() const {
-  std::string encoded;
-  base::Base64Encode(
-      base::StringPiece(reinterpret_cast<const char*>(bytes_->front()),
-                        bytes_->size()),
-      &encoded);
-  return encoded;
-}
-
-// static
-Binary Binary::fromBase64(const String& base64, bool* success) {
-  std::string decoded;
-  *success = base::Base64Decode(base::StringPiece(base64), &decoded);
-  if (*success) {
-    return Binary::fromString(std::move(decoded));
-  }
-  return Binary();
-}
-
-// static
-Binary Binary::fromRefCounted(scoped_refptr<base::RefCountedMemory> memory) {
-  return Binary(memory);
-}
-
-// static
-Binary Binary::fromVector(std::vector<uint8_t> data) {
-  return Binary(base::RefCountedBytes::TakeVector(&data));
-}
-
-// static
-Binary Binary::fromString(std::string data) {
-  return Binary(base::RefCountedString::TakeString(&data));
-}
-}  // namespace protocol
diff --git a/chrome/browser/devtools/protocol_string.h b/chrome/browser/devtools/protocol_string.h
deleted file mode 100644
index b7eea7c..0000000
--- a/chrome/browser/devtools/protocol_string.h
+++ /dev/null
@@ -1,115 +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 CHROME_BROWSER_DEVTOOLS_PROTOCOL_STRING_H_
-#define CHROME_BROWSER_DEVTOOLS_PROTOCOL_STRING_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/strings/string_number_conversions.h"
-
-namespace base {
-class Value;
-}
-
-namespace protocol {
-
-class Value;
-
-using String = std::string;
-
-class StringBuilder {
- public:
-  StringBuilder();
-  ~StringBuilder();
-  void append(const String&);
-  void append(char);
-  void append(const char*, size_t);
-  String toString();
-  void reserveCapacity(size_t);
-
- private:
-  std::string string_;
-};
-
-class StringUtil {
- public:
-  static String substring(const String& s, unsigned pos, unsigned len) {
-    return s.substr(pos, len);
-  }
-  static String fromInteger(int number) { return base::NumberToString(number); }
-  static String fromDouble(double number) {
-    String s = base::NumberToString(number);
-    if (!s.empty() && s[0] == '.')
-      s = "0" + s;
-    return s;
-  }
-  static double toDouble(const char* s, size_t len, bool* ok) {
-    double v = 0.0;
-    *ok = base::StringToDouble(std::string(s, len), &v);
-    return *ok ? v : 0.0;
-  }
-  static size_t find(const String& s, const char* needle) {
-    return s.find(needle);
-  }
-  static size_t find(const String& s, const String& needle) {
-    return s.find(needle);
-  }
-  static const size_t kNotFound = static_cast<size_t>(-1);
-  static void builderAppend(StringBuilder& builder, const String& s) {
-    builder.append(s);
-  }
-  static void builderAppend(StringBuilder& builder, char c) {
-    builder.append(c);
-  }
-  static void builderAppend(StringBuilder& builder, const char* s, size_t len) {
-    builder.append(s, len);
-  }
-  static void builderAppendQuotedString(StringBuilder& builder,
-                                        const String& str);
-  static void builderReserve(StringBuilder& builder, unsigned capacity) {
-    builder.reserveCapacity(capacity);
-  }
-  static String builderToString(StringBuilder& builder) {
-    return builder.toString();
-  }
-
-  static std::unique_ptr<protocol::Value> parseJSON(const String&);
-};
-
-// A read-only sequence of uninterpreted bytes with reference-counted storage.
-class Binary {
- public:
-  Binary(const Binary&);
-  Binary();
-  ~Binary();
-
-  const uint8_t* data() const { return bytes_->front(); }
-  size_t size() const { return bytes_->size(); }
-  scoped_refptr<base::RefCountedMemory> bytes() const { return bytes_; }
-
-  String toBase64() const;
-
-  static Binary fromBase64(const String& base64, bool* success);
-  static Binary fromRefCounted(scoped_refptr<base::RefCountedMemory> memory);
-  static Binary fromVector(std::vector<uint8_t> data);
-  static Binary fromString(std::string data);
-
- private:
-  explicit Binary(scoped_refptr<base::RefCountedMemory> bytes);
-  scoped_refptr<base::RefCountedMemory> bytes_;
-};
-
-std::unique_ptr<protocol::Value> toProtocolValue(const base::Value* value,
-                                                 int depth);
-std::unique_ptr<base::Value> toBaseValue(protocol::Value* value, int depth);
-
-}  // namespace protocol
-
-#endif  // CHROME_BROWSER_DEVTOOLS_PROTOCOL_STRING_H_
diff --git a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
index 2f191e7..131ab81a 100644
--- a/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
+++ b/chrome/browser/extensions/api/socket/tcp_socket_unittest.cc
@@ -541,6 +541,21 @@
     NOTIMPLEMENTED();
     return nullptr;
   }
+  std::unique_ptr<net::ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<net::StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const net::HostPortPair& endpoint,
+      const net::ProxyServer& proxy_server,
+      net::HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      net::NextProto negotiated_protocol,
+      net::ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
 
  private:
   std::vector<std::unique_ptr<net::StaticSocketDataProvider>> providers_;
diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc
index b08a21c..b6fdacf3 100644
--- a/chrome/browser/extensions/extension_tab_util.cc
+++ b/chrome/browser/extensions/extension_tab_util.cc
@@ -759,7 +759,7 @@
 
 // static
 bool ExtensionTabUtil::BrowserSupportsTabs(Browser* browser) {
-  return browser && browser->tab_strip_model() && !browser->is_devtools();
+  return browser && !browser->is_devtools();
 }
 
 }  // namespace extensions
diff --git a/chrome/browser/feature_engagement/bookmark/bookmark_tracker_unittest.cc b/chrome/browser/feature_engagement/bookmark/bookmark_tracker_unittest.cc
index a35725ed..d734353 100644
--- a/chrome/browser/feature_engagement/bookmark/bookmark_tracker_unittest.cc
+++ b/chrome/browser/feature_engagement/bookmark/bookmark_tracker_unittest.cc
@@ -149,8 +149,9 @@
         "name:bookmark_clicked;comparator:any;window:3650;storage:3650";
     bookmark_params["session_rate"] = "<=3";
     bookmark_params["availability"] = "any";
-    bookmark_params["x_date_released_in_seconds"] = base::NumberToString(
-        first_run::GetFirstRunSentinelCreationTime().ToDoubleT());
+    bookmark_params["x_date_released_in_seconds"] =
+        base::NumberToString(static_cast<int64_t>(
+            first_run::GetFirstRunSentinelCreationTime().ToDoubleT()));
 
     SetFeatureParams(kIPHBookmarkFeature, bookmark_params);
 
diff --git a/chrome/browser/feature_engagement/feature_tracker_unittest.cc b/chrome/browser/feature_engagement/feature_tracker_unittest.cc
index 72ac55b..2132fef 100644
--- a/chrome/browser/feature_engagement/feature_tracker_unittest.cc
+++ b/chrome/browser/feature_engagement/feature_tracker_unittest.cc
@@ -265,8 +265,9 @@
 TEST_F(FeatureTrackerParamsTest, TestIsNewUser_DefaultTime) {
   // Setting the experiment timestamp equal to the first run sentinel timestamp.
   std::map<std::string, std::string> new_tab_params;
-  new_tab_params["x_date_released_in_seconds"] = base::NumberToString(
-      first_run::GetFirstRunSentinelCreationTime().ToDoubleT());
+  new_tab_params["x_date_released_in_seconds"] =
+      base::NumberToString(static_cast<int64_t>(
+          first_run::GetFirstRunSentinelCreationTime().ToDoubleT()));
   SetFeatureParams(kIPHNewTabFeature, new_tab_params);
 
   std::unique_ptr<MockTestFeatureTracker> mock_feature_tracker =
@@ -282,9 +283,10 @@
   // Setting the experiment timestamp equal to one second older than what is
   // considered a new user.
   std::map<std::string, std::string> new_tab_params;
-  new_tab_params["x_date_released_in_seconds"] = base::NumberToString(
-      first_run::GetFirstRunSentinelCreationTime().ToDoubleT() +
-      base::TimeDelta::FromHours(24).InSeconds() + 1);
+  new_tab_params["x_date_released_in_seconds"] =
+      base::NumberToString(static_cast<int64_t>(
+          first_run::GetFirstRunSentinelCreationTime().ToDoubleT() +
+          base::TimeDelta::FromHours(24).InSeconds() + 1));
   SetFeatureParams(kIPHNewTabFeature, new_tab_params);
 
   std::unique_ptr<MockTestFeatureTracker> mock_feature_tracker =
@@ -303,8 +305,9 @@
 
   // Setting the experiment timestamp equal to the limit of what is considered a
   // new user.
-  new_tab_params["x_date_released_in_seconds"] = base::NumberToString(
-      first_run::GetFirstRunSentinelCreationTime().ToDoubleT());
+  new_tab_params["x_date_released_in_seconds"] =
+      base::NumberToString(static_cast<int64_t>(
+          first_run::GetFirstRunSentinelCreationTime().ToDoubleT()));
   SetFeatureParams(kIPHNewTabFeature, new_tab_params);
 
   std::unique_ptr<MockTestFeatureTracker> mock_feature_tracker =
@@ -323,9 +326,10 @@
 
   // Setting the experiment timestamp equal to one second older than what is
   // considered a new user.
-  new_tab_params["x_date_released_in_seconds"] = base::NumberToString(
-      first_run::GetFirstRunSentinelCreationTime().ToDoubleT() +
-      base::TimeDelta::FromHours(28).InSeconds() + 1);
+  new_tab_params["x_date_released_in_seconds"] =
+      base::NumberToString(static_cast<int64_t>(
+          first_run::GetFirstRunSentinelCreationTime().ToDoubleT() +
+          base::TimeDelta::FromHours(28).InSeconds() + 1));
   SetFeatureParams(kIPHNewTabFeature, new_tab_params);
 
   std::unique_ptr<MockTestFeatureTracker> mock_feature_tracker =
diff --git a/chrome/browser/feature_engagement/incognito_window/incognito_window_tracker_unittest.cc b/chrome/browser/feature_engagement/incognito_window/incognito_window_tracker_unittest.cc
index 056f3b62..120b50c0 100644
--- a/chrome/browser/feature_engagement/incognito_window/incognito_window_tracker_unittest.cc
+++ b/chrome/browser/feature_engagement/incognito_window/incognito_window_tracker_unittest.cc
@@ -153,8 +153,8 @@
     incognito_window_params["session_rate"] = "<=3";
     incognito_window_params["availability"] = "any";
     incognito_window_params["x_date_released_in_seconds"] =
-        base::NumberToString(
-            first_run::GetFirstRunSentinelCreationTime().ToDoubleT());
+        base::NumberToString(static_cast<int64_t>(
+            first_run::GetFirstRunSentinelCreationTime().ToDoubleT()));
     SetFeatureParams(kIPHIncognitoWindowFeature, incognito_window_params);
 
     // Start the DesktopSessionDurationTracker to track active session time.
diff --git a/chrome/browser/feature_engagement/new_tab/new_tab_tracker_unittest.cc b/chrome/browser/feature_engagement/new_tab/new_tab_tracker_unittest.cc
index b0e75048..c6829da 100644
--- a/chrome/browser/feature_engagement/new_tab/new_tab_tracker_unittest.cc
+++ b/chrome/browser/feature_engagement/new_tab/new_tab_tracker_unittest.cc
@@ -159,8 +159,9 @@
         "name:new_tab_clicked;comparator:any;window:3650;storage:3650";
     new_tab_params["session_rate"] = "<=3";
     new_tab_params["availability"] = "any";
-    new_tab_params["x_date_released_in_seconds"] = base::NumberToString(
-        first_run::GetFirstRunSentinelCreationTime().ToDoubleT());
+    new_tab_params["x_date_released_in_seconds"] =
+        base::NumberToString(static_cast<int64_t>(
+            first_run::GetFirstRunSentinelCreationTime().ToDoubleT()));
 
     SetFeatureParams(kIPHNewTabFeature, new_tab_params);
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index dc3df5b..3b28f4a 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -527,6 +527,11 @@
     "expiry_milestone": 76
   },
   {
+    "name": "disable-best-effort-tasks",
+    "owners": [ "catan-team@chromium.org" ],
+    "expiry_milestone": 75
+  },
+  {
     "name": "disable-captive-portal-bypass-proxy",
     // "owners": [ "your-team" ],
     "expiry_milestone": 76
@@ -2034,7 +2039,7 @@
   },
   {
     "name": "enable-webvr",
-    // "owners": [ "your-team" ],
+    "owners": [ "//third_party/blink/renderer/modules/vr/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   },
   {
@@ -2429,7 +2434,7 @@
   },
   {
     "name": "oculus-vr",
-    // "owners": [ "your-team" ],
+    "owners": [ "//device/vr/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   },
   {
@@ -2609,7 +2614,7 @@
   },
   {
     "name": "openvr",
-    // "owners": [ "your-team" ],
+    "owners": [ "//device/vr/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   },
   {
@@ -3196,32 +3201,32 @@
   },
   {
     "name": "webvr-vsync-align",
-    // "owners": [ "your-team" ],
+    "owners": [ "//chrome/browser/android/vr/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   },
   {
     "name": "webxr",
-    // "owners": [ "your-team" ],
-    "expiry_milestone": 76
+    "owners": [ "//third_party/blink/renderer/modules/xr/OWNERS", "xr-dev@chromium.org" ],
+    "expiry_milestone": 79
   },
   {
     "name": "webxr-gamepad-support",
-    // "owners": [ "your-team" ],
+    "owners": [ "//third_party/blink/renderer/modules/xr/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   },
   {
     "name": "webxr-hit-test",
-    // "owners": [ "your-team" ],
+    "owners": [ "//third_party/blink/renderer/modules/xr/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   },
   {
     "name": "webxr-orientation-sensor-device",
-    // "owners": [ "your-team" ],
+    "owners": [ "//device/vr/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   },
   {
     "name": "webxr-render-path",
-    // "owners": [ "your-team" ],
+    "owners": [ "//chrome/browser/android/vr/OWNERS", "xr-dev@chromium.org", "klausw@chromium.org" ],
     "expiry_milestone": 76
   },
   {
@@ -3230,8 +3235,13 @@
     "expiry_milestone": 76
   },
   {
+    "name": "windows-mixed-reality",
+    "owners": [ "//device/vr/OWNERS", "xr-dev@chromium.org" ],
+    "expiry_milestone": 76
+  },
+  {
     "name": "xr-sandbox",
-    // "owners": [ "your-team" ],
+    "owners": [ "//chrome/services/isolated_xr_device/OWNERS", "xr-dev@chromium.org" ],
     "expiry_milestone": 76
   }
 
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index c1fba06..6c48d7f 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -325,6 +325,15 @@
     "With this flag on, desktop share picker window will not let the user "
     "choose whether to share audio.";
 
+const char kDisableBestEffortTasksName[] = "Skip best effort tasks";
+const char kDisableBestEffortTasksDescription[] =
+    "With this flag on, tasks of the lowest priority will not be executed "
+    "until shutdown. The queue of low priority tasks can increase memory usage."
+    "Also, while it should be possible to use Chrome almost normally with this "
+    "flag, it is expected that some non-visible operations such as writing "
+    "user data to disk, cleaning caches, reporting metrics or updating "
+    "components won't be performed until shutdown.";
+
 const char kDisableIpcFloodingProtectionName[] =
     "Disable IPC flooding protection";
 const char kDisableIpcFloodingProtectionDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 426000f..b8d2cc25 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -241,6 +241,9 @@
 extern const char kDisableAudioForDesktopShareName[];
 extern const char kDisableAudioForDesktopShareDescription[];
 
+extern const char kDisableBestEffortTasksName[];
+extern const char kDisableBestEffortTasksDescription[];
+
 extern const char kDisableIpcFloodingProtectionName[];
 extern const char kDisableIpcFloodingProtectionDescription[];
 
diff --git a/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc b/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc
index 240a6ca1..0c585a5 100644
--- a/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc
+++ b/chrome/browser/media/router/discovery/dial/device_description_fetcher_unittest.cc
@@ -21,6 +21,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+using testing::HasSubstr;
+
 namespace media_router {
 
 class TestDeviceDescriptionFetcher : public DeviceDescriptionFetcher {
@@ -55,18 +57,6 @@
  public:
   DeviceDescriptionFetcherTest() : url_("http://127.0.0.1/description.xml") {}
 
-  void ExpectSuccess(const GURL& expected_app_url,
-                     const std::string& expected_description) {
-    expected_app_url_ = expected_app_url;
-    expected_description_ = expected_description;
-    EXPECT_CALL(*this, DoOnSuccess());
-  }
-
-  void ExpectError(const std::string expected_error) {
-    expected_error_ = expected_error;
-    EXPECT_CALL(*this, DoOnError());
-  }
-
   void StartRequest() {
     description_fetcher_ = std::make_unique<TestDeviceDescriptionFetcher>(
         url_,
@@ -80,41 +70,22 @@
   }
 
  protected:
+  MOCK_METHOD1(OnSuccess, void(const DialDeviceDescriptionData&));
+  MOCK_METHOD1(OnError, void(const std::string&));
+
   base::test::ScopedTaskEnvironment environment_;
   const GURL url_;
   network::TestURLLoaderFactory loader_factory_;
-  base::OnceCallback<void(const DialDeviceDescriptionData&)> success_cb_;
-  base::OnceCallback<void(const std::string&)> error_cb_;
   std::unique_ptr<TestDeviceDescriptionFetcher> description_fetcher_;
-  GURL expected_app_url_;
-  std::string expected_description_;
-  std::string expected_error_;
 
  private:
-  MOCK_METHOD0(DoOnSuccess, void());
-  MOCK_METHOD0(DoOnError, void());
-
-  void OnSuccess(const DialDeviceDescriptionData& description) {
-    EXPECT_EQ(expected_app_url_, description.app_url);
-    EXPECT_EQ(expected_description_, description.device_description);
-    DoOnSuccess();
-    description_fetcher_.reset();
-  }
-
-  void OnError(const std::string& message) {
-    EXPECT_TRUE(message.find(expected_error_) != std::string::npos)
-        << "[" << expected_error_ << "] not found in message [" << message
-        << "]";
-    DoOnError();
-    description_fetcher_.reset();
-  }
-
   DISALLOW_COPY_AND_ASSIGN(DeviceDescriptionFetcherTest);
 };
 
 TEST_F(DeviceDescriptionFetcherTest, FetchSuccessful) {
   std::string body("<xml>description</xml>");
-  ExpectSuccess(GURL("http://127.0.0.1/apps"), body);
+  EXPECT_CALL(*this, OnSuccess(DialDeviceDescriptionData(
+                         body, GURL("http://127.0.0.1/apps"))));
   network::ResourceResponseHead head;
   head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
   head.headers->AddHeader("Application-URL: http://127.0.0.1/apps");
@@ -126,7 +97,8 @@
 
 TEST_F(DeviceDescriptionFetcherTest, FetchSuccessfulAppUrlWithTrailingSlash) {
   std::string body("<xml>description</xml>");
-  ExpectSuccess(GURL("http://127.0.0.1/apps"), body);
+  EXPECT_CALL(*this, OnSuccess(DialDeviceDescriptionData(
+                         body, GURL("http://127.0.0.1/apps"))));
   network::ResourceResponseHead head;
   head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
   head.headers->AddHeader("Application-URL: http://127.0.0.1/apps/");
@@ -137,7 +109,7 @@
 }
 
 TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnMissingDescription) {
-  ExpectError("404");
+  EXPECT_CALL(*this, OnError(HasSubstr("404")));
   loader_factory_.AddResponse(
       url_, network::ResourceResponseHead(), "",
       network::URLLoaderCompletionStatus(net::HTTP_NOT_FOUND));
@@ -146,7 +118,7 @@
 
 TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnMissingAppUrl) {
   std::string body("<xml>description</xml>");
-  ExpectError("Missing or empty Application-URL:");
+  EXPECT_CALL(*this, OnError(HasSubstr("Missing or empty Application-URL:")));
   network::URLLoaderCompletionStatus status;
   status.decoded_body_length = body.size();
   loader_factory_.AddResponse(url_, network::ResourceResponseHead(), body,
@@ -155,7 +127,7 @@
 }
 
 TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnEmptyAppUrl) {
-  ExpectError("Missing or empty Application-URL:");
+  EXPECT_CALL(*this, OnError(HasSubstr("Missing or empty Application-URL:")));
   std::string body("<xml>description</xml>");
   network::ResourceResponseHead head;
   head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
@@ -167,7 +139,7 @@
 }
 
 TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnInvalidAppUrl) {
-  ExpectError("Invalid Application-URL:");
+  EXPECT_CALL(*this, OnError(HasSubstr("Invalid Application-URL:")));
   std::string body("<xml>description</xml>");
   network::ResourceResponseHead head;
   head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
@@ -179,7 +151,7 @@
 }
 
 TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnEmptyDescription) {
-  ExpectError("Missing or empty response");
+  EXPECT_CALL(*this, OnError(HasSubstr("Missing or empty response")));
   network::ResourceResponseHead head;
   head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
   head.headers->AddHeader("Application-URL: http://127.0.0.1/apps");
@@ -190,7 +162,7 @@
 }
 
 TEST_F(DeviceDescriptionFetcherTest, FetchFailsOnBadDescription) {
-  ExpectError("Invalid response encoding");
+  EXPECT_CALL(*this, OnError(HasSubstr("Invalid response encoding")));
   std::string body("\xfc\x9c\xbf\x80\xbf\x80");
   network::ResourceResponseHead head;
   head.headers = base::MakeRefCounted<net::HttpResponseHeaders>("");
diff --git a/chrome/browser/media/router/discovery/dial/dial_device_data.cc b/chrome/browser/media/router/discovery/dial/dial_device_data.cc
index 357ef768..bc52975 100644
--- a/chrome/browser/media/router/discovery/dial/dial_device_data.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_device_data.cc
@@ -73,4 +73,10 @@
     const GURL& app_url)
     : device_description(device_description), app_url(app_url) {}
 
+bool DialDeviceDescriptionData::operator==(
+    const DialDeviceDescriptionData& other_data) const {
+  return device_description == other_data.device_description &&
+         app_url == other_data.app_url;
+}
+
 }  // namespace media_router
diff --git a/chrome/browser/media/router/discovery/dial/dial_device_data.h b/chrome/browser/media/router/discovery/dial/dial_device_data.h
index 58d9249..76d31da5 100644
--- a/chrome/browser/media/router/discovery/dial/dial_device_data.h
+++ b/chrome/browser/media/router/discovery/dial/dial_device_data.h
@@ -96,6 +96,9 @@
   DialDeviceDescriptionData() = default;
   DialDeviceDescriptionData(const std::string& device_description,
                             const GURL& app_url);
+  ~DialDeviceDescriptionData() = default;
+
+  bool operator==(const DialDeviceDescriptionData& other_data) const;
 
   std::string device_description;
   GURL app_url;
diff --git a/chrome/browser/media/router/discovery/dial/dial_url_fetcher_unittest.cc b/chrome/browser/media/router/discovery/dial/dial_url_fetcher_unittest.cc
index 62b3362..8f100be 100644
--- a/chrome/browser/media/router/discovery/dial/dial_url_fetcher_unittest.cc
+++ b/chrome/browser/media/router/discovery/dial/dial_url_fetcher_unittest.cc
@@ -23,21 +23,15 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
+using testing::_;
+using testing::HasSubstr;
+
 namespace media_router {
 
 class DialURLFetcherTest : public testing::Test {
  public:
   DialURLFetcherTest() : url_("http://127.0.0.1/app/Youtube") {}
 
-  void ExpectSuccess(const std::string& expected_app_info) {
-    EXPECT_CALL(*this, OnSuccess(expected_app_info));
-  }
-
-  void ExpectError(const std::string& expected_error) {
-    expected_error_ = expected_error;
-    EXPECT_CALL(*this, DoOnError());
-  }
-
   void StartGetRequest() {
     fetcher_ = std::make_unique<TestDialURLFetcher>(
         base::BindOnce(&DialURLFetcherTest::OnSuccess, base::Unretained(this)),
@@ -48,29 +42,21 @@
   }
 
  protected:
+  MOCK_METHOD1(OnSuccess, void(const std::string&));
+  MOCK_METHOD2(OnError, void(int, const std::string&));
+
   base::test::ScopedTaskEnvironment environment_;
   network::TestURLLoaderFactory loader_factory_;
   const GURL url_;
-  std::string expected_error_;
   std::unique_ptr<TestDialURLFetcher> fetcher_;
 
  private:
-  MOCK_METHOD1(OnSuccess, void(const std::string&));
-  MOCK_METHOD0(DoOnError, void());
-
-  void OnError(int response_code, const std::string& message) {
-    EXPECT_TRUE(message.find(expected_error_) != std::string::npos)
-        << "[" << expected_error_ << "] not found in message [" << message
-        << "]";
-    DoOnError();
-  }
-
   DISALLOW_COPY_AND_ASSIGN(DialURLFetcherTest);
 };
 
 TEST_F(DialURLFetcherTest, FetchSuccessful) {
   std::string body("<xml>appInfo</xml>");
-  ExpectSuccess(body);
+  EXPECT_CALL(*this, OnSuccess(body));
   network::URLLoaderCompletionStatus status;
   status.decoded_body_length = body.size();
   loader_factory_.AddResponse(url_, network::ResourceResponseHead(), body,
@@ -79,8 +65,7 @@
 }
 
 TEST_F(DialURLFetcherTest, FetchFailsOnMissingAppInfo) {
-  ExpectError("404");
-
+  EXPECT_CALL(*this, OnError(404, HasSubstr("404")));
   loader_factory_.AddResponse(
       url_, network::ResourceResponseHead(), "",
       network::URLLoaderCompletionStatus(net::HTTP_NOT_FOUND));
@@ -88,15 +73,14 @@
 }
 
 TEST_F(DialURLFetcherTest, FetchFailsOnEmptyAppInfo) {
-  ExpectError("Missing or empty response");
-
+  EXPECT_CALL(*this, OnError(_, HasSubstr("Missing or empty response")));
   loader_factory_.AddResponse(url_, network::ResourceResponseHead(), "",
                               network::URLLoaderCompletionStatus());
   StartGetRequest();
 }
 
 TEST_F(DialURLFetcherTest, FetchFailsOnBadAppInfo) {
-  ExpectError("Invalid response encoding");
+  EXPECT_CALL(*this, OnError(_, "Invalid response encoding"));
   std::string body("\xfc\x9c\xbf\x80\xbf\x80");
   network::URLLoaderCompletionStatus status;
   status.decoded_body_length = body.size();
diff --git a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
index 45fcaa9..5519d97 100644
--- a/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
+++ b/chrome/browser/media/router/mojo/media_router_mojo_impl_unittest.cc
@@ -136,22 +136,6 @@
 
 }  // namespace
 
-class RouteResponseCallbackHandler {
- public:
-  void Invoke(mojom::RoutePresentationConnectionPtr connection,
-              const RouteRequestResult& result) {
-    DoInvoke(result.route(), result.presentation_id(), result.error(),
-             result.result_code(), connection);
-  }
-  // TODO(btolsch): Convert this to pass move-only types directly to the mock.
-  MOCK_METHOD5(DoInvoke,
-               void(const MediaRoute* route,
-                    const std::string& presentation_id,
-                    const std::string& error_text,
-                    RouteRequestResult::ResultCode result_code,
-                    mojom::RoutePresentationConnectionPtr& connection));
-};
-
 class MediaRouterMojoImplTest : public MediaRouterMojoTest {
  public:
   MediaRouterMojoImplTest() {}
diff --git a/chrome/browser/media/router/presentation/local_presentation_manager_unittest.cc b/chrome/browser/media/router/presentation/local_presentation_manager_unittest.cc
index ef3778b2..2266087 100644
--- a/chrome/browser/media/router/presentation/local_presentation_manager_unittest.cc
+++ b/chrome/browser/media/router/presentation/local_presentation_manager_unittest.cc
@@ -27,16 +27,10 @@
 
 class MockReceiverConnectionAvailableCallback {
  public:
-  void OnReceiverConnectionAvailable(
-      PresentationInfoPtr presentation_info,
-      content::PresentationConnectionPtr controller_conn,
-      content::PresentationConnectionRequest receiver_conn_request) {
-    OnReceiverConnectionAvailableRaw(*presentation_info, controller_conn.get());
-  }
-
-  MOCK_METHOD2(OnReceiverConnectionAvailableRaw,
-               void(const PresentationInfo&,
-                    blink::mojom::PresentationConnection*));
+  MOCK_METHOD3(OnReceiverConnectionAvailable,
+               void(PresentationInfoPtr,
+                    content::PresentationConnectionPtr,
+                    content::PresentationConnectionRequest));
 };
 
 class LocalPresentationManagerTest : public ::testing::Test {
@@ -179,7 +173,7 @@
   VerifyPresentationsSize(0);
 
   RegisterController(std::move(controller));
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _));
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _));
   RegisterReceiver(receiver_callback);
 }
 
@@ -191,7 +185,7 @@
   VerifyPresentationsSize(0);
 
   RegisterController(std::move(controller));
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _));
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _));
   RegisterReceiver(receiver_callback);
   UnregisterReceiver();
 
@@ -206,7 +200,7 @@
   VerifyPresentationsSize(0);
 
   RegisterController(std::move(controller));
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _));
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _));
   RegisterReceiver(receiver_callback);
   UnregisterController();
 
@@ -221,7 +215,7 @@
   VerifyPresentationsSize(0);
 
   RegisterController(std::move(controller));
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _));
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _));
   RegisterReceiver(receiver_callback);
   UnregisterReceiver();
   UnregisterController();
@@ -237,7 +231,7 @@
   VerifyPresentationsSize(0);
 
   RegisterController(std::move(controller));
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _));
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _));
   RegisterReceiver(receiver_callback);
   UnregisterController();
   UnregisterReceiver();
@@ -255,7 +249,7 @@
                      std::move(controller2));
 
   MockReceiverConnectionAvailableCallback receiver_callback;
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _))
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _))
       .Times(2);
   RegisterReceiver(receiver_callback);
 }
@@ -267,7 +261,7 @@
                      std::move(controller1));
 
   MockReceiverConnectionAvailableCallback receiver_callback;
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _))
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _))
       .Times(2);
   RegisterReceiver(receiver_callback);
 
@@ -286,7 +280,7 @@
                      std::move(controller2));
 
   MockReceiverConnectionAvailableCallback receiver_callback;
-  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailableRaw(_, _))
+  EXPECT_CALL(receiver_callback, OnReceiverConnectionAvailable(_, _, _))
       .Times(2);
   RegisterReceiver(receiver_callback);
   UnregisterController(content::GlobalFrameRoutingId(1, 1));
@@ -300,7 +294,7 @@
   RegisterController(kPresentationId, std::move(controller1));
 
   MockReceiverConnectionAvailableCallback receiver_callback1;
-  EXPECT_CALL(receiver_callback1, OnReceiverConnectionAvailableRaw(_, _))
+  EXPECT_CALL(receiver_callback1, OnReceiverConnectionAvailable(_, _, _))
       .Times(1);
   RegisterReceiver(kPresentationId, receiver_callback1);
 
@@ -308,7 +302,7 @@
   RegisterController(kPresentationId2, std::move(controller2));
 
   MockReceiverConnectionAvailableCallback receiver_callback2;
-  EXPECT_CALL(receiver_callback2, OnReceiverConnectionAvailableRaw(_, _))
+  EXPECT_CALL(receiver_callback2, OnReceiverConnectionAvailable(_, _, _))
       .Times(1);
   RegisterReceiver(kPresentationId2, receiver_callback2);
 
diff --git a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
index c66da3f..1b43d8c 100644
--- a/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
+++ b/chrome/browser/media/router/providers/wired_display/wired_display_media_route_provider_unittest.cc
@@ -49,8 +49,7 @@
  public:
   MOCK_METHOD2(Start,
                void(const std::string& presentation_id, const GURL& start_url));
-  void Terminate() override { TerminateInternal(); }
-  MOCK_METHOD0(TerminateInternal, void());
+  MOCK_METHOD0(Terminate, void());
   MOCK_METHOD0(ExitFullscreen, void());
 
   void SetTerminationCallback(base::OnceClosure termination_callback) {
@@ -341,7 +340,7 @@
   // Terminate the route.
   EXPECT_CALL(callback, TerminateRoute(base::Optional<std::string>(),
                                        RouteRequestResult::OK));
-  EXPECT_CALL(*receiver_creator_.receiver(), TerminateInternal());
+  EXPECT_CALL(*receiver_creator_.receiver(), Terminate());
   EXPECT_CALL(router_,
               OnPresentationConnectionStateChanged(
                   presentation_id,
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.cc b/chrome/browser/media/router/test/media_router_mojo_test.cc
index d94165c..a7a3045 100644
--- a/chrome/browser/media/router/test/media_router_mojo_test.cc
+++ b/chrome/browser/media/router/test/media_router_mojo_test.cc
@@ -43,21 +43,6 @@
   return route;
 }
 
-class RouteResponseCallbackHandler {
- public:
-  void Invoke(mojom::RoutePresentationConnectionPtr connection,
-              const RouteRequestResult& result) {
-    DoInvoke(result.route(), result.presentation_id(), result.error(),
-             result.result_code(), connection);
-  }
-  MOCK_METHOD5(DoInvoke,
-               void(const MediaRoute* route,
-                    const std::string& presentation_id,
-                    const std::string& error_text,
-                    RouteRequestResult::ResultCode result_code,
-                    mojom::RoutePresentationConnectionPtr& connection));
-};
-
 class SendMessageCallbackHandler {
  public:
   MOCK_METHOD1(Invoke, void(bool));
@@ -513,4 +498,14 @@
                         mojom::MediaRouteProviderConfigPtr config) {}));
 }
 
+RouteResponseCallbackHandler::RouteResponseCallbackHandler() = default;
+RouteResponseCallbackHandler::~RouteResponseCallbackHandler() = default;
+
+void RouteResponseCallbackHandler::Invoke(
+    mojom::RoutePresentationConnectionPtr connection,
+    const RouteRequestResult& result) {
+  DoInvoke(result.route(), result.presentation_id(), result.error(),
+           result.result_code(), connection);
+}
+
 }  // namespace media_router
diff --git a/chrome/browser/media/router/test/media_router_mojo_test.h b/chrome/browser/media/router/test/media_router_mojo_test.h
index 5396af1..981977c 100644
--- a/chrome/browser/media/router/test/media_router_mojo_test.h
+++ b/chrome/browser/media/router/test/media_router_mojo_test.h
@@ -335,6 +335,27 @@
   DISALLOW_COPY_AND_ASSIGN(MediaRouterMojoTest);
 };
 
+// An object whose Invoke method can be passed as a MediaRouteResponseCallback.
+class RouteResponseCallbackHandler {
+ public:
+  RouteResponseCallbackHandler();
+  ~RouteResponseCallbackHandler();
+
+  // Calls DoInvoke with the contents of |connection| and |result|.
+  void Invoke(mojom::RoutePresentationConnectionPtr connection,
+              const RouteRequestResult& result);
+
+  MOCK_METHOD5(DoInvoke,
+               void(const MediaRoute* route,
+                    const std::string& presentation_id,
+                    const std::string& error_text,
+                    RouteRequestResult::ResultCode result_code,
+                    mojom::RoutePresentationConnectionPtr& connection));
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(RouteResponseCallbackHandler);
+};
+
 }  // namespace media_router
 
 #endif  // CHROME_BROWSER_MEDIA_ROUTER_TEST_MEDIA_ROUTER_MOJO_TEST_H_
diff --git a/chrome/browser/no_best_effort_tasks_browsertest.cc b/chrome/browser/no_best_effort_tasks_browsertest.cc
index 882aa79..27936974 100644
--- a/chrome/browser/no_best_effort_tasks_browsertest.cc
+++ b/chrome/browser/no_best_effort_tasks_browsertest.cc
@@ -80,7 +80,7 @@
 
  private:
   void SetUpCommandLine(base::CommandLine* command_line) override {
-    command_line->AppendSwitch(switches::kDisableBackgroundTasks);
+    command_line->AppendSwitch(switches::kDisableBestEffortTasks);
     InProcessBrowserTest::SetUpCommandLine(command_line);
   }
 
diff --git a/chrome/browser/offline_pages/recent_tab_helper_unittest.cc b/chrome/browser/offline_pages/recent_tab_helper_unittest.cc
index 00cb8fb..13b9861 100644
--- a/chrome/browser/offline_pages/recent_tab_helper_unittest.cc
+++ b/chrome/browser/offline_pages/recent_tab_helper_unittest.cc
@@ -99,6 +99,9 @@
   // Advances main thread time to trigger the snapshot controller's timeouts.
   void FastForwardSnapshotController();
 
+  void NavigateAndCommit(const GURL& url);
+  void Reload();
+
   // Navigates to the URL and commit as if it has been typed in the address bar.
   // Note: we need this to simulate navigations to the same URL that more like a
   // reload and not same page. NavigateAndCommit simulates a click on a link
@@ -151,6 +154,9 @@
   void SetLastPathCreatedByArchiver(const base::FilePath& file_path) override {}
 
  private:
+  void StartAndCommitNavigation(
+      std::unique_ptr<content::NavigationSimulator> simulator);
+
   void OnGetAllPagesDone(const std::vector<OfflinePageItem>& result);
 
   RecentTabHelper* recent_tab_helper_;   // Owned by WebContents.
@@ -269,11 +275,40 @@
   (*mocked_main_runner_)->FastForwardBy(kLongDelay);
 }
 
+void RecentTabHelperTest::StartAndCommitNavigation(
+    std::unique_ptr<content::NavigationSimulator> simulator) {
+  simulator->SetAutoAdvance(false);
+  simulator->Start();
+
+  // Need to flush the task queue manually since there may be async tasks
+  // spawned by navigation start that must finish before commit. Since this test
+  // harness swaps out the main thread, NavigationSimulator cannot pump the task
+  // queue itself to finish navigations.
+  //
+  // TODO(csharrison): This can probably be removed and replaced with either the
+  // NavigationSimulator controlling the mock task runner, or by the snapshot
+  // controller using a (mock) timer instead of PostDelayedTask.
+  RunUntilIdle();
+  simulator->Commit();
+}
+
+void RecentTabHelperTest::NavigateAndCommit(const GURL& url) {
+  StartAndCommitNavigation(content::NavigationSimulator::CreateBrowserInitiated(
+      url, web_contents()));
+}
+
+void RecentTabHelperTest::Reload() {
+  auto simulator = content::NavigationSimulator::CreateBrowserInitiated(
+      web_contents()->GetLastCommittedURL(), web_contents());
+  simulator->SetReloadType(content::ReloadType::NORMAL);
+  StartAndCommitNavigation(std::move(simulator));
+}
+
 void RecentTabHelperTest::NavigateAndCommitTyped(const GURL& url) {
   auto simulator =
       content::NavigationSimulator::CreateBrowserInitiated(url, web_contents());
   simulator->SetTransition(ui::PAGE_TRANSITION_TYPED);
-  simulator->Commit();
+  StartAndCommitNavigation(std::move(simulator));
 }
 
 void RecentTabHelperTest::NavigateAndCommitPost(const GURL& url) {
@@ -281,8 +316,7 @@
       content::NavigationSimulator::CreateRendererInitiated(url, main_rfh());
   simulator->SetMethod("POST");
   simulator->SetTransition(ui::PAGE_TRANSITION_FORM_SUBMIT);
-  simulator->Start();
-  simulator->Commit();
+  StartAndCommitNavigation(std::move(simulator));
 }
 
 ClientId RecentTabHelperTest::NewDownloadClientId() {
@@ -1052,7 +1086,8 @@
 
   // Starts a reload and hides the tab before it minimally load. The previous
   // snapshot should be removed.
-  content::NavigationSimulator::Reload(web_contents());
+  Reload();
+
   recent_tab_helper()->OnVisibilityChanged(content::Visibility::HIDDEN);
   RunUntilIdle();
   EXPECT_EQ(1U, page_added_count());
diff --git a/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc b/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc
index 37001c9..aec68ef5 100644
--- a/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc
+++ b/chrome/browser/password_manager/password_store_signin_notifier_impl_unittest.cc
@@ -5,11 +5,9 @@
 #include "chrome/browser/password_manager/password_store_signin_notifier_impl.h"
 
 #include "base/bind.h"
-#include "chrome/browser/signin/account_fetcher_service_factory.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/password_manager/core/browser/mock_password_store.h"
-#include "components/signin/core/browser/account_fetcher_service.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/identity/public/cpp/accounts_mutator.h"
 #include "services/identity/public/cpp/primary_account_mutator.h"
@@ -81,8 +79,6 @@
   testing::Mock::VerifyAndClearExpectations(store_.get());
   EXPECT_CALL(*store_, ClearGaiaPasswordHash("username2"));
   auto* identity_manager = identity_test_env()->identity_manager();
-  AccountFetcherService* account_fetcher_service =
-      AccountFetcherServiceFactory::GetForProfile(testing_profile_.get());
   identity_manager->GetAccountsMutator()->AddOrUpdateAccount(
       /*gaia_id=*/"secondary_account_id",
       /*email=*/"username2",
@@ -91,7 +87,8 @@
       signin_metrics::SourceForRefreshTokenOperation::kUnknown);
   // This call is necessary to ensure that the account removal is fully
   // processed in this testing context.
-  account_fetcher_service->EnableNetworkFetchesForTest();
+  identity_test_env()
+      ->EnableOnAccountUpdatedAndOnAccountRemovedWithInfoCallbacks();
   identity_manager->GetAccountsMutator()->RemoveAccount(
       "secondary_account_id",
       signin_metrics::SourceForRefreshTokenOperation::kUserMenu_RemoveAccount);
diff --git a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
index f8feb38..c68aa2c 100644
--- a/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
+++ b/chrome/browser/policy/cloud/user_policy_signin_service_unittest.cc
@@ -19,9 +19,7 @@
 #include "chrome/browser/policy/cloud/user_policy_signin_service_factory.h"
 #include "chrome/browser/prefs/browser_prefs.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/account_fetcher_service_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
-#include "chrome/browser/signin/fake_account_fetcher_service_builder.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/browser/signin/signin_util.h"
 #include "chrome/browser/signin/test_signin_client_builder.h"
@@ -36,8 +34,6 @@
 #include "components/policy/core/common/cloud/user_cloud_policy_manager.h"
 #include "components/policy/core/common/schema_registry.h"
 #include "components/prefs/pref_service.h"
-#include "components/signin/core/browser/account_fetcher_service.h"
-#include "components/signin/core/browser/fake_account_fetcher_service.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/notification_details.h"
@@ -174,9 +170,6 @@
         std::unique_ptr<sync_preferences::PrefServiceSyncable>(
             std::move(prefs)));
     builder.AddTestingFactory(
-        AccountFetcherServiceFactory::GetInstance(),
-        base::BindRepeating(&FakeAccountFetcherServiceBuilder::BuildForTests));
-    builder.AddTestingFactory(
         ChromeSigninClientFactory::GetInstance(),
         base::BindRepeating(&signin::BuildTestSigninClient));
     profile_ = IdentityTestEnvironmentProfileAdaptor::
@@ -786,9 +779,8 @@
   // Explicitly forcing this call is necessary for the clearing of the primary
   // account to result in the account being fully removed in this testing
   // context.
-  AccountFetcherService* account_fetcher_service =
-      AccountFetcherServiceFactory::GetForProfile(profile_.get());
-  account_fetcher_service->EnableNetworkFetchesForTest();
+  identity_test_env()
+      ->EnableOnAccountUpdatedAndOnAccountRemovedWithInfoCallbacks();
 #endif
 
   ASSERT_NO_FATAL_FAILURE(TestSuccessfulSignin());
diff --git a/chrome/browser/profiling_host/memlog_browsertest.cc b/chrome/browser/profiling_host/memlog_browsertest.cc
index 00a2008..d4fbee9 100644
--- a/chrome/browser/profiling_host/memlog_browsertest.cc
+++ b/chrome/browser/profiling_host/memlog_browsertest.cc
@@ -87,7 +87,8 @@
 
 // Ensure invocations via TracingController can generate a valid JSON file with
 // expected data.
-IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, EndToEnd) {
+// TODO(crbug.com/843467): Disabled due to flakiness.
+IN_PROC_BROWSER_TEST_P(MemlogBrowserTest, DISABLED_EndToEnd) {
   LOG(INFO) << "Memlog mode: " << static_cast<int>(GetParam().mode);
   LOG(INFO) << "Memlog stack mode: " << static_cast<int>(GetParam().stack_mode);
   LOG(INFO) << "Stream samples: " << GetParam().stream_samples;
diff --git a/chrome/browser/resources/chromeos/switch_access/menu_manager.js b/chrome/browser/resources/chromeos/switch_access/menu_manager.js
index fd6b8fea..7765b57 100644
--- a/chrome/browser/resources/chromeos/switch_access/menu_manager.js
+++ b/chrome/browser/resources/chromeos/switch_access/menu_manager.js
@@ -67,14 +67,18 @@
           MessageHandler.Destination.MENU_PANEL, 'setActions', actions);
     }
 
-    this.node_ = this.menuNode();
+    const firstNode =
+        this.menuNode().find({role: chrome.automation.RoleType.BUTTON});
+    if (firstNode) {
+      this.node_ = firstNode;
+      this.updateFocusRing_();
+    }
 
     if (navNode.location)
       chrome.accessibilityPrivate.setSwitchAccessMenuState(
           true, navNode.location, actions.length);
     else
       console.log('Unable to show Switch Access menu.');
-    this.moveForward();
   }
 
   /**
diff --git a/chrome/browser/resources/feedback/js/event_handler.js b/chrome/browser/resources/feedback/js/event_handler.js
index b53143f..e0fff4c 100644
--- a/chrome/browser/resources/feedback/js/event_handler.js
+++ b/chrome/browser/resources/feedback/js/event_handler.js
@@ -82,6 +82,7 @@
   'A3E3DE9E9F16B41D4A2FAD106BD6CA76B94A0C94',  // http://crbug.com/908458
   'C2ABD68C33A5B485971C9638B80D6A2E9CBA78C4',  // http://crbug.com/908458
   'B41E7F08E1179CC03CBD1F49E57CF353A40ADE07',  // http://crbug.com/908458
+  'A948368FC53BE437A55FEB414106E207925482F5',  // ChromeOS Files App.
 ];
 
 /**
diff --git a/chrome/browser/resources/print_preview/new/model.js b/chrome/browser/resources/print_preview/new/model.js
index 6635130f..7497283 100644
--- a/chrome/browser/resources/print_preview/new/model.js
+++ b/chrome/browser/resources/print_preview/new/model.js
@@ -317,7 +317,7 @@
     'updateSettingsFromDestination_(destination.capabilities)',
     'updateSettingsAvailabilityFromDocumentSettings_(' +
         'documentSettings.isModifiable, documentSettings.hasCssMediaStyles,' +
-        'documentSettings.hasSelection, documentSettings.isScalingDisabled)',
+        'documentSettings.hasSelection)',
     'updateHeaderFooterAvailable_(' +
         'margins, settings.margins.value, ' +
         'settings.customMargins.value, settings.mediaSize.value)',
@@ -412,11 +412,8 @@
     this.set('settings.fitToPage.unavailableValue', !isSaveAsPDF);
     this.set(
         'settings.fitToPage.available',
-        !knownSizeToSaveAsPdf && !this.documentSettings.isModifiable &&
-            !this.documentSettings.isScalingDisabled);
-    this.set(
-        'settings.scaling.available',
-        !knownSizeToSaveAsPdf && !this.documentSettings.isScalingDisabled);
+        !knownSizeToSaveAsPdf && !this.documentSettings.isModifiable);
+    this.set('settings.scaling.available', !knownSizeToSaveAsPdf);
     const caps = (!!this.destination && !!this.destination.capabilities) ?
         this.destination.capabilities.printer :
         null;
diff --git a/chrome/browser/resources/settings/site_settings/site_entry.js b/chrome/browser/resources/settings/site_settings/site_entry.js
index 07da4cb24..6dcf0e7 100644
--- a/chrome/browser/resources/settings/site_settings/site_entry.js
+++ b/chrome/browser/resources/settings/site_settings/site_entry.js
@@ -403,7 +403,7 @@
       origins: []
     };
     for (let i = 0; i < this.siteGroup.origins.length; ++i) {
-      const updatedOrigin = this.siteGroup.origins[i];
+      const updatedOrigin = Object.assign({}, this.siteGroup.origins[i]);
       if (updatedOrigin.numCookies > 0 || updatedOrigin.usage > 0) {
         updatedOrigin.hasPermissionSettings = false;
         updatedSiteGroup.origins.push(updatedOrigin);
@@ -448,7 +448,7 @@
       origins: []
     };
     for (let i = 0; i < this.siteGroup.origins.length; ++i) {
-      const updatedOrigin = this.siteGroup.origins[i];
+      const updatedOrigin = Object.assign({}, this.siteGroup.origins[i]);
       if (updatedOrigin.hasPermissionSettings) {
         updatedOrigin.numCookies = 0;
         updatedOrigin.usage = 0;
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/BUILD.gn b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/BUILD.gn
index 1a1f119..c369018 100644
--- a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/BUILD.gn
+++ b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/BUILD.gn
@@ -12,7 +12,15 @@
 
 js_library("nux_ntp_background") {
   deps = [
+    ":ntp_background_proxy",
     "../:navigation_behavior",
     "../shared:nux_types",
   ]
 }
+
+js_library("ntp_background_proxy") {
+  deps = [
+    "//ui/webui/resources/js:cr",
+  ]
+  externs_list = [ "$externs_path/chrome_send.js" ]
+}
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/ntp_background_proxy.html b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/ntp_background_proxy.html
new file mode 100644
index 0000000..a15c5167
--- /dev/null
+++ b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/ntp_background_proxy.html
@@ -0,0 +1,2 @@
+<link rel="import" href="chrome://resources/html/cr.html">
+<script src="ntp_background_proxy.js"></script>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/ntp_background_proxy.js b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/ntp_background_proxy.js
new file mode 100644
index 0000000..6df82b4f
--- /dev/null
+++ b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/ntp_background_proxy.js
@@ -0,0 +1,36 @@
+// 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.
+
+cr.define('nux', function() {
+  /**
+   * @typedef {{
+   *   id: number,
+   *   imageUrl: string,
+   *   title: string,
+   * }}
+   */
+  let NtpBackgroundData;
+
+  /** @interface */
+  class NtpBackgroundProxy {
+    /** @return {!Promise<!Array<!nux.NtpBackgroundData>>} */
+    getBackgrounds() {}
+  }
+
+  /** @implements {nux.NtpBackgroundProxy} */
+  class NtpBackgroundProxyImpl {
+    /** @override */
+    getBackgrounds() {
+      return cr.sendWithPromise('getBackgrounds');
+    }
+  }
+
+  cr.addSingletonGetter(NtpBackgroundProxyImpl);
+
+  return {
+    NtpBackgroundData: NtpBackgroundData,
+    NtpBackgroundProxy: NtpBackgroundProxy,
+    NtpBackgroundProxyImpl: NtpBackgroundProxyImpl,
+  };
+});
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html
index 814e202..952a45c 100644
--- a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html
+++ b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.html
@@ -2,6 +2,8 @@
 
 <link rel="import" href="chrome://resources/cr_elements/paper_button_style_css.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
+<link rel="import" href="../navigation_behavior.html">
+<link rel="import" href="ntp_background_proxy.html">
 
 <dom-module id="nux-ntp-background">
   <template>
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js
index a7328bd..7733660 100644
--- a/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js
+++ b/chrome/browser/resources/welcome/onboarding_welcome/ntp_background/nux_ntp_background.js
@@ -11,6 +11,23 @@
     indicatorModel: Object,
   },
 
+  /** @private {?Array<!nux.NtpBackgroundData>} */
+  backgrounds_: null,
+
+  /** @private {?nux.NtpBackgroundProxy} */
+  ntpBackgroundProxy_: null,
+
+  /** @override */
+  ready: function() {
+    this.ntpBackgroundProxy_ = nux.NtpBackgroundProxyImpl.getInstance();
+  },
+
+  onRouteEnter: function() {
+    this.ntpBackgroundProxy_.getBackgrounds().then((backgrounds) => {
+      this.backgrounds_ = backgrounds;
+    });
+  },
+
   /** @private */
   onNextClicked_: function() {
     welcome.navigateToNextStep();
diff --git a/chrome/browser/resources/welcome/onboarding_welcome/onboarding_welcome_resources.grd b/chrome/browser/resources/welcome/onboarding_welcome/onboarding_welcome_resources.grd
index cdde3c1..0ba3e7f 100644
--- a/chrome/browser/resources/welcome/onboarding_welcome/onboarding_welcome_resources.grd
+++ b/chrome/browser/resources/welcome/onboarding_welcome/onboarding_welcome_resources.grd
@@ -228,6 +228,12 @@
       <structure name="IDR_NUX_NTP_BACKGROUND_JS"
                  file="ntp_background\nux_ntp_background.js"
                  type="chrome_html" />
+      <structure name="IDR_NUX_NTP_BACKGROUND_PROXY_HTML"
+                 file="ntp_background\ntp_background_proxy.html"
+                 type="chrome_html" />
+      <structure name="IDR_NUX_NTP_BACKGROUND_PROXY_JS"
+                 file="ntp_background\ntp_background_proxy.js"
+                 type="chrome_html" />
     </structures>
   </release>
 </grit>
diff --git a/chrome/browser/safe_browsing/advanced_protection_status_manager_unittest.cc b/chrome/browser/safe_browsing/advanced_protection_status_manager_unittest.cc
index dddbbffc..a0a3808 100644
--- a/chrome/browser/safe_browsing/advanced_protection_status_manager_unittest.cc
+++ b/chrome/browser/safe_browsing/advanced_protection_status_manager_unittest.cc
@@ -7,12 +7,10 @@
 #include "base/bind.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "chrome/browser/safe_browsing/advanced_protection_status_manager_factory.h"
-#include "chrome/browser/signin/account_fetcher_service_factory.h"
 #include "chrome/browser/signin/identity_test_environment_profile_adaptor.h"
 #include "chrome/test/base/testing_profile.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
-#include "components/signin/core/browser/account_fetcher_service.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "services/identity/public/cpp/accounts_mutator.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -348,11 +346,10 @@
   EXPECT_TRUE(aps_manager.is_under_advanced_protection());
   EXPECT_TRUE(aps_manager.IsRefreshScheduled());
 
-  AccountFetcherService* account_fetcher_service =
-      AccountFetcherServiceFactory::GetForProfile(testing_profile_.get());
   // This call is necessary to ensure that the account removal is fully
   // processed in this testing context.
-  account_fetcher_service->EnableNetworkFetchesForTest();
+  identity_test_env()
+      ->EnableOnAccountUpdatedAndOnAccountRemovedWithInfoCallbacks();
   identity_test_env()->identity_manager()->GetAccountsMutator()->RemoveAccount(
       account_id,
       signin_metrics::SourceForRefreshTokenOperation::kUserMenu_RemoveAccount);
diff --git a/chrome/browser/search/instant_service.cc b/chrome/browser/search/instant_service.cc
index 6525f94..3179fb4 100644
--- a/chrome/browser/search/instant_service.cc
+++ b/chrome/browser/search/instant_service.cc
@@ -78,13 +78,16 @@
   return background_info;
 }
 
-std::unique_ptr<base::DictionaryValue> NtpCustomBackgroundDefaults() {
-  std::unique_ptr<base::DictionaryValue> defaults =
-      std::make_unique<base::DictionaryValue>();
-  defaults->SetString(kNtpCustomBackgroundURL, std::string());
-  defaults->SetString(kNtpCustomBackgroundAttributionLine1, std::string());
-  defaults->SetString(kNtpCustomBackgroundAttributionLine2, std::string());
-  defaults->SetString(kNtpCustomBackgroundAttributionActionURL, std::string());
+base::Value NtpCustomBackgroundDefaults() {
+  base::Value defaults(base::Value::Type::DICTIONARY);
+  defaults.SetKey(kNtpCustomBackgroundURL,
+                  base::Value(base::Value::Type::STRING));
+  defaults.SetKey(kNtpCustomBackgroundAttributionLine1,
+                  base::Value(base::Value::Type::STRING));
+  defaults.SetKey(kNtpCustomBackgroundAttributionLine2,
+                  base::Value(base::Value::Type::STRING));
+  defaults.SetKey(kNtpCustomBackgroundAttributionActionURL,
+                  base::Value(base::Value::Type::STRING));
   return defaults;
 }
 
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc
index 1d55e53..3b275aa2 100644
--- a/chrome/browser/search/local_ntp_source.cc
+++ b/chrome/browser/search/local_ntp_source.cc
@@ -1306,7 +1306,9 @@
   base::Optional<SearchSuggestData> data =
       search_suggest_service_->search_suggest_data();
 
-  search_suggest_service_->SuggestionsDisplayed();
+  if (data.has_value()) {
+    search_suggest_service_->SuggestionsDisplayed();
+  }
   scoped_refptr<base::RefCountedString> result;
   std::string js;
   base::JSONWriter::Write(*ConvertSearchSuggestDataToDict(data), &js);
diff --git a/chrome/browser/search/search_suggest/search_suggest_service.cc b/chrome/browser/search/search_suggest/search_suggest_service.cc
index c2e2dae..475e506 100644
--- a/chrome/browser/search/search_suggest/search_suggest_service.cc
+++ b/chrome/browser/search/search_suggest/search_suggest_service.cc
@@ -44,16 +44,15 @@
 // Default value for max_impressions specified by the VASCO team.
 const int kDefaultMaxImpressions = 4;
 
-std::unique_ptr<base::DictionaryValue> ImpressionDictDefaults() {
-  std::unique_ptr<base::DictionaryValue> defaults =
-      std::make_unique<base::DictionaryValue>();
-  defaults->SetInteger(kFirstShownTimeMs, 0);
-  defaults->SetInteger(kImpressionCapExpireTimeMs, 0);
-  defaults->SetInteger(kImpressionsCount, 0);
-  defaults->SetBoolean(kIsRequestFrozen, false);
-  defaults->SetInteger(kMaxImpressions, kDefaultMaxImpressions);
-  defaults->SetInteger(kRequestFreezeTimeMs, 0);
-  defaults->SetInteger(kRequestFrozenTimeMs, 0);
+base::Value ImpressionDictDefaults() {
+  base::Value defaults(base::Value::Type::DICTIONARY);
+  defaults.SetKey(kFirstShownTimeMs, base::Value(0));
+  defaults.SetKey(kImpressionCapExpireTimeMs, base::Value(0));
+  defaults.SetKey(kImpressionsCount, base::Value(0));
+  defaults.SetKey(kIsRequestFrozen, base::Value(false));
+  defaults.SetKey(kMaxImpressions, base::Value(kDefaultMaxImpressions));
+  defaults.SetKey(kRequestFreezeTimeMs, base::Value(0));
+  defaults.SetKey(kRequestFrozenTimeMs, base::Value(0));
   return defaults;
 }
 
@@ -67,10 +66,14 @@
   SigninObserver(identity::IdentityManager* identity_manager,
                  const SigninStatusChangedCallback& callback)
       : identity_manager_(identity_manager), callback_(callback) {
-    identity_manager_->AddObserver(this);
+    if (identity_manager_)
+      identity_manager_->AddObserver(this);
   }
 
-  ~SigninObserver() override { identity_manager_->RemoveObserver(this); }
+  ~SigninObserver() override {
+    if (identity_manager_)
+      identity_manager_->RemoveObserver(this);
+  }
 
   bool SignedIn() {
     return !identity_manager_->GetAccountsInCookieJar()
@@ -85,6 +88,7 @@
     callback_.Run();
   }
 
+  // May be nullptr in tests.
   identity::IdentityManager* const identity_manager_;
   SigninStatusChangedCallback callback_;
 };
@@ -111,6 +115,11 @@
   DCHECK(!observers_.might_have_observers());
 }
 
+const base::Optional<SearchSuggestData>&
+SearchSuggestService::search_suggest_data() const {
+  return search_suggest_data_;
+}
+
 void SearchSuggestService::Refresh() {
   const std::string blocklist = GetBlocklistAsString();
   MaybeLoadWithBlocklist(blocklist);
diff --git a/chrome/browser/search/search_suggest/search_suggest_service.h b/chrome/browser/search/search_suggest/search_suggest_service.h
index 513eb9d..59077fc 100644
--- a/chrome/browser/search/search_suggest/search_suggest_service.h
+++ b/chrome/browser/search/search_suggest/search_suggest_service.h
@@ -37,9 +37,8 @@
   void Shutdown() override;
 
   // Returns the currently cached SearchSuggestData, if any.
-  const base::Optional<SearchSuggestData>& search_suggest_data() const {
-    return search_suggest_data_;
-  }
+  // Virtual for testing.
+  virtual const base::Optional<SearchSuggestData>& search_suggest_data() const;
 
   const SearchSuggestLoader::Status& search_suggest_status() const {
     return search_suggest_status_;
@@ -50,7 +49,8 @@
   // reason. Otherwise requests an asynchronous refresh from the network. After
   // the update completes, regardless of success, OnSearchSuggestDataUpdated
   // will be called on the observers.
-  void Refresh();
+  // Virtual for testing.
+  virtual void Refresh();
 
   // Add/remove observers. All observers must unregister themselves before the
   // SearchSuggestService is destroyed.
@@ -99,7 +99,18 @@
 
   // Called when suggestions are displayed on the NTP, clears the cached data
   // and updates timestamps and impression counts.
-  void SuggestionsDisplayed();
+  // Virtual for testing.
+  virtual void SuggestionsDisplayed();
+
+ protected:
+  // Called when a Refresh() is requested. If |status|==OK, |data| will contain
+  // the fetched data. Otherwise |data| will be nullopt and |status| will
+  // indicate if the request failed or the reason it was not sent.
+  //
+  // If the |status|==FATAL_ERROR freeze future requests until the request
+  // freeze interval has elapsed.
+  void SearchSuggestDataLoaded(SearchSuggestLoader::Status status,
+                               const base::Optional<SearchSuggestData>& data);
 
  private:
   class SigninObserver;
@@ -110,15 +121,6 @@
   // calls SearchSuggestDataLoaded with the reason a request was not made.
   void MaybeLoadWithBlocklist(const std::string& blocklist);
 
-  // Called when a Refresh() is requested. If |status|==OK, |data| will contain
-  // the fetched data. Otherwise |data| will be nullopt and |status| will
-  // indicate if the request failed or the reason it was not sent.
-  //
-  // If the |status|==FATAL_ERROR freeze future requests until the request
-  // freeze interval has elapsed.
-  void SearchSuggestDataLoaded(SearchSuggestLoader::Status status,
-                               const base::Optional<SearchSuggestData>& data);
-
   void NotifyObservers();
 
   // Returns true if the number of impressions has reached the maxmium allowed
diff --git a/chrome/browser/signin/fake_profile_oauth2_token_service_builder.cc b/chrome/browser/signin/fake_profile_oauth2_token_service_builder.cc
deleted file mode 100644
index e659f25..0000000
--- a/chrome/browser/signin/fake_profile_oauth2_token_service_builder.cc
+++ /dev/null
@@ -1,27 +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.
-
-#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
-
-#include <utility>
-
-#include "chrome/browser/profiles/profile.h"
-#include "components/signin/core/browser/fake_profile_oauth2_token_service.h"
-
-std::unique_ptr<KeyedService> BuildFakeProfileOAuth2TokenService(
-    content::BrowserContext* context) {
-  Profile* profile = Profile::FromBrowserContext(context);
-  std::unique_ptr<FakeProfileOAuth2TokenService> service(
-      new FakeProfileOAuth2TokenService(profile->GetPrefs()));
-  return std::move(service);
-}
-
-std::unique_ptr<KeyedService> BuildAutoIssuingFakeProfileOAuth2TokenService(
-    content::BrowserContext* context) {
-  Profile* profile = Profile::FromBrowserContext(context);
-  std::unique_ptr<FakeProfileOAuth2TokenService> service(
-      new FakeProfileOAuth2TokenService(profile->GetPrefs()));
-  service->set_auto_post_fetch_response_on_message_loop(true);
-  return std::move(service);
-}
diff --git a/chrome/browser/signin/fake_profile_oauth2_token_service_builder.h b/chrome/browser/signin/fake_profile_oauth2_token_service_builder.h
deleted file mode 100644
index 7cb1d0d1..0000000
--- a/chrome/browser/signin/fake_profile_oauth2_token_service_builder.h
+++ /dev/null
@@ -1,29 +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.
-
-#ifndef CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_BUILDER_H_
-#define CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_BUILDER_H_
-
-#include <memory>
-
-class KeyedService;
-
-namespace content {
-class BrowserContext;
-}
-
-// Helper function to be used with
-// BrowserContextKeyedServiceFactory::SetTestingFactory() that returns a
-// FakeProfileOAuth2TokenService object.
-std::unique_ptr<KeyedService> BuildFakeProfileOAuth2TokenService(
-    content::BrowserContext* context);
-
-// Helper function to be used with
-// BrowserContextKeyedServiceFactory::SetTestingFactory() that creates a
-// FakeProfileOAuth2TokenService object that posts fetch responses on the
-// current message loop.
-std::unique_ptr<KeyedService> BuildAutoIssuingFakeProfileOAuth2TokenService(
-    content::BrowserContext* context);
-
-#endif  // CHROME_BROWSER_SIGNIN_FAKE_PROFILE_OAUTH2_TOKEN_SERVICE_BUILDER_H_
diff --git a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc
index 91b04c9..5711ff6 100644
--- a/chrome/browser/signin/identity_test_environment_profile_adaptor.cc
+++ b/chrome/browser/signin/identity_test_environment_profile_adaptor.cc
@@ -8,7 +8,6 @@
 #include "chrome/browser/signin/account_fetcher_service_factory.h"
 #include "chrome/browser/signin/account_tracker_service_factory.h"
 #include "chrome/browser/signin/chrome_signin_client_factory.h"
-#include "chrome/browser/signin/fake_profile_oauth2_token_service_builder.h"
 #include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
 #include "chrome/browser/signin/gaia_cookie_manager_service_test_util.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
@@ -52,6 +51,15 @@
       std::make_unique<TestImageDecoder>());
   return account_fetcher_service;
 }
+
+// Testing factory that creates a FakeProfileOAuth2TokenService.
+std::unique_ptr<KeyedService> BuildFakeProfileOAuth2TokenService(
+    content::BrowserContext* context) {
+  Profile* profile = Profile::FromBrowserContext(context);
+  std::unique_ptr<FakeProfileOAuth2TokenService> service(
+      new FakeProfileOAuth2TokenService(profile->GetPrefs()));
+  return std::move(service);
+}
 }  // namespace
 
 // static
diff --git a/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_provider.cc b/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_provider.cc
index 0dd08d98..934eae1 100644
--- a/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_provider.cc
+++ b/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_provider.cc
@@ -27,7 +27,7 @@
   new_results.reserve(app_names.size());
   for (auto& app_name : app_names) {
     new_results.emplace_back(
-        std::make_unique<CrostiniRepositorySearchResult>(profile_, app_name));
+        std::make_unique<CrostiniRepositorySearchResult>(app_name));
     // Todo(https://crbug.com/921429): Improve relevance logic, this will likely
     // be implemented in garcon then piped to Chrome
     new_results.back()->set_relevance(static_cast<float>(query_.size()) /
diff --git a/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.cc b/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.cc
index 7d01e2c..9df56f4 100644
--- a/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.cc
+++ b/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.cc
@@ -10,8 +10,6 @@
 #include "ash/public/cpp/app_list/vector_icons/vector_icons.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/chromeos/crostini/crostini_package_service.h"
-#include "chrome/browser/chromeos/crostini/crostini_util.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/grit/generated_resources.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -22,14 +20,13 @@
 namespace {
 
 // TODO(https://crbug.com/921429): Need UX spec.
-constexpr SkColor kListIconColor = SkColorSetARGB(0xDE, 0x00, 0x00, 0x00);
+constexpr SkColor kListIconColor = SkColorSetARGB(0xDE, 0xAD, 0xAD, 0xAD);
 
 }  // namespace
 
 CrostiniRepositorySearchResult::CrostiniRepositorySearchResult(
-    Profile* profile,
     const std::string& app_name)
-    : profile_(profile), app_name_(app_name), weak_ptr_factory_(this) {
+    : app_name_(app_name), weak_ptr_factory_(this) {
   // TODO(https://crbug.com/921429): Need UX spec.
   set_id("crostini:" + app_name_);
   SetResultType(ash::SearchResultType::kOmnibox);
@@ -40,35 +37,14 @@
       icon, AppListConfig::instance().search_list_icon_dimension(),
       kListIconColor));
   SetTitle(l10n_util::GetStringFUTF16(
-      IDS_CROSTINI_REPOSITORY_SEARCH_RESULT_TITLE_PLACEHOLDER_TEXT,
+      IDS_CROSTINI_REPOSITORY_SEARCH_RESULT_PLACEHOLDER_TEXT,
       base::UTF8ToUTF16(app_name_)));
-  SetDetails(l10n_util::GetStringUTF16(
-      IDS_CROSTINI_REPOSITORY_SEARCH_RESULT_DETAILS_PLACEHOLDER_TEXT));
 }
 
 CrostiniRepositorySearchResult::~CrostiniRepositorySearchResult() = default;
 
-// TODO(https://crbug.com/921429): Change Open() to open up an installation
-// confirmation dialogue that then calls crostini::InstallLinuxPackageFromApt.
-
-void CrostiniRepositorySearchResult::OnOpen(
-    const crostini::LinuxPackageInfo& package_info) {
-  if (package_info.success) {
-    crostini::CrostiniPackageService::GetForProfile(profile_)
-        ->InstallLinuxPackageFromApt(crostini::kCrostiniDefaultVmName,
-                                     crostini::kCrostiniDefaultContainerName,
-                                     package_info.package_id,
-                                     base::DoNothing());
-  }
-}
-
 void CrostiniRepositorySearchResult::Open(int event_flags) {
-  crostini::CrostiniManager::GetForProfile(profile_)
-      ->GetLinuxPackageInfoFromApt(
-          crostini::kCrostiniDefaultVmName,
-          crostini::kCrostiniDefaultContainerName, app_name_,
-          base::BindOnce(&CrostiniRepositorySearchResult::OnOpen,
-                         weak_ptr_factory_.GetWeakPtr()));
+  // TODO(https://crbug.com/921429): connect to logic in crostini_manager.
 }
 
 }  // namespace app_list
diff --git a/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.h b/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.h
index d289cd4..cdcbb36 100644
--- a/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.h
+++ b/chrome/browser/ui/app_list/search/crostini/crostini_repository_search_result.h
@@ -8,26 +8,22 @@
 #include <string>
 
 #include "base/macros.h"
-#include "chrome/browser/chromeos/crostini/crostini_manager.h"
 #include "chrome/browser/ui/app_list/app_context_menu_delegate.h"
 #include "chrome/browser/ui/app_list/search/chrome_search_result.h"
 
-class Profile;
-
 namespace app_list {
 
 class CrostiniRepositorySearchResult : public ChromeSearchResult {
  public:
-  CrostiniRepositorySearchResult(Profile* profile, const std::string& app_name);
+  explicit CrostiniRepositorySearchResult(const std::string& app_name);
   ~CrostiniRepositorySearchResult() override;
 
   // ChromeSearchResult overrides:
+  // TODO(https://crbug.com/921429): Implement open functionality (confirmation
+  // and installation of app).
   void Open(int event_flags) override;
 
  private:
-  void OnOpen(const crostini::LinuxPackageInfo& package);
-
-  Profile* profile_;
   std::string app_name_;
   base::WeakPtrFactory<CrostiniRepositorySearchResult> weak_ptr_factory_;
 
diff --git a/chrome/browser/ui/ash/assistant/device_actions.cc b/chrome/browser/ui/ash/assistant/device_actions.cc
index 17bdd82..83bd19e 100644
--- a/chrome/browser/ui/ash/assistant/device_actions.cc
+++ b/chrome/browser/ui/ash/assistant/device_actions.cc
@@ -41,6 +41,22 @@
   return app_id.empty() ? AppStatus::UNAVAILABLE : AppStatus::AVAILABLE;
 }
 
+base::Optional<std::string> GetActivity(const std::string& package_name) {
+  auto* prefs = ArcAppListPrefs::Get(ProfileManager::GetActiveUserProfile());
+  if (!prefs) {
+    LOG(ERROR) << "ArcAppListPrefs is not available.";
+    return base::nullopt;
+  }
+  std::string app_id = prefs->GetAppIdByPackageName(package_name);
+
+  if (!app_id.empty()) {
+    std::unique_ptr<ArcAppListPrefs::AppInfo> app_info = prefs->GetApp(app_id);
+    return base::Optional<std::string>(app_info->activity);
+  }
+
+  return base::nullopt;
+}
+
 }  // namespace
 
 DeviceActions::DeviceActions() {}
@@ -123,12 +139,24 @@
     std::move(callback).Run(false);
     return;
   }
+  auto& package_name = app_info->package_name;
 
   arc::mojom::ActivityNamePtr activity = arc::mojom::ActivityName::New();
-  activity->package_name = app_info->package_name;
+  activity->package_name = package_name;
   auto intent = arc::mojom::IntentInfo::New();
   if (!app_info->intent.empty()) {
     intent->data = app_info->intent;
+  } else {
+    // Intent is not specified to resolve the activity, set default activity
+    // name.
+    auto activity_name = GetActivity(package_name);
+    if (!activity_name.has_value()) {
+      LOG(ERROR) << "No activity resolved from package name.";
+      std::move(callback).Run(false);
+      return;
+    }
+
+    activity->activity_name = activity_name.value();
   }
   helper->HandleIntent(std::move(intent), std::move(activity));
 
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc
index b9bfa3f..118e8e7 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.cc
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -131,6 +131,15 @@
   NOTIMPLEMENTED();
 }
 
+void TestWallpaperController::ShowAlwaysOnTopWallpaper(
+    const base::FilePath& image_path) {
+  ++show_always_on_top_wallpaper_count_;
+}
+
+void TestWallpaperController::RemoveAlwaysOnTopWallpaper() {
+  ++remove_always_on_top_wallpaper_count_;
+}
+
 void TestWallpaperController::RemoveUserWallpaper(
     ash::mojom::WallpaperUserInfoPtr user_info,
     const std::string& wallpaper_files_id) {
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h
index 9ae5e9a..83b97fe0 100644
--- a/chrome/browser/ui/ash/test_wallpaper_controller.h
+++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -30,6 +30,12 @@
     return set_default_wallpaper_count_;
   }
   int set_custom_wallpaper_count() const { return set_custom_wallpaper_count_; }
+  int show_always_on_top_wallpaper_count() const {
+    return show_always_on_top_wallpaper_count_;
+  }
+  int remove_always_on_top_wallpaper_count() const {
+    return remove_always_on_top_wallpaper_count_;
+  }
 
   // Returns a mojo interface pointer bound to this object.
   ash::mojom::WallpaperControllerPtr CreateInterfacePtr();
@@ -86,6 +92,8 @@
   void ShowUserWallpaper(ash::mojom::WallpaperUserInfoPtr user_info) override;
   void ShowSigninWallpaper() override;
   void ShowOneShotWallpaper(const gfx::ImageSkia& image) override;
+  void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override;
+  void RemoveAlwaysOnTopWallpaper() override;
   void RemoveUserWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
                            const std::string& wallpaper_files_id) override;
   void RemovePolicyWallpaper(ash::mojom::WallpaperUserInfoPtr user_info,
@@ -125,6 +133,8 @@
   int remove_user_wallpaper_count_ = 0;
   int set_default_wallpaper_count_ = 0;
   int set_custom_wallpaper_count_ = 0;
+  int show_always_on_top_wallpaper_count_ = 0;
+  int remove_always_on_top_wallpaper_count_ = 0;
 
   mojo::AssociatedInterfacePtrSet<ash::mojom::WallpaperObserver>
       test_observers_;
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.cc b/chrome/browser/ui/ash/wallpaper_controller_client.cc
index b9f05c9..c57544c 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.cc
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.cc
@@ -342,6 +342,15 @@
   wallpaper_controller_->ShowSigninWallpaper();
 }
 
+void WallpaperControllerClient::ShowAlwaysOnTopWallpaper(
+    const base::FilePath& image_path) {
+  wallpaper_controller_->ShowAlwaysOnTopWallpaper(image_path);
+}
+
+void WallpaperControllerClient::RemoveAlwaysOnTopWallpaper() {
+  wallpaper_controller_->RemoveAlwaysOnTopWallpaper();
+}
+
 void WallpaperControllerClient::RemoveUserWallpaper(
     const AccountId& account_id) {
   ash::mojom::WallpaperUserInfoPtr user_info =
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client.h b/chrome/browser/ui/ash/wallpaper_controller_client.h
index 5c4e79e..6fe8c58 100644
--- a/chrome/browser/ui/ash/wallpaper_controller_client.h
+++ b/chrome/browser/ui/ash/wallpaper_controller_client.h
@@ -73,6 +73,8 @@
                                    ash::WallpaperLayout layout);
   void ShowUserWallpaper(const AccountId& account_id);
   void ShowSigninWallpaper();
+  void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path);
+  void RemoveAlwaysOnTopWallpaper();
   void RemoveUserWallpaper(const AccountId& account_id);
   void RemovePolicyWallpaper(const AccountId& account_id);
   void GetOfflineWallpaperList(
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 559a297..4ab52f4 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -386,8 +386,9 @@
     : extension_registry_observer_(this),
       type_(params.type),
       profile_(params.profile),
-      window_(NULL),
-      tab_strip_model_delegate_(new chrome::BrowserTabStripModelDelegate(this)),
+      window_(nullptr),
+      tab_strip_model_delegate_(
+          std::make_unique<chrome::BrowserTabStripModelDelegate>(this)),
       tab_strip_model_(
           std::make_unique<TabStripModel>(tab_strip_model_delegate_.get(),
                                           params.profile)),
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index 0307e6f..63d8ce4 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -284,7 +284,10 @@
     location_bar_model->swap(location_bar_model_);
   }
 #endif
+
+  // Never nullptr.
   TabStripModel* tab_strip_model() const { return tab_strip_model_.get(); }
+
   chrome::BrowserCommandController* command_controller() {
     return command_controller_.get();
   }
@@ -966,8 +969,8 @@
   // This Browser's window.
   BrowserWindow* window_;
 
-  std::unique_ptr<TabStripModelDelegate> tab_strip_model_delegate_;
-  std::unique_ptr<TabStripModel> tab_strip_model_;
+  std::unique_ptr<TabStripModelDelegate> const tab_strip_model_delegate_;
+  std::unique_ptr<TabStripModel> const tab_strip_model_;
 
   // The application name that is also the name of the window to the shell.
   // This name should be set when:
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc
index 94396ef..be0b0ca7 100644
--- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc
+++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger.cc
@@ -83,21 +83,25 @@
 }
 
 void ReopenTabInProductHelpTrigger::NewTabOpened() {
-  if (trigger_state_ != ACTIVE_TAB_CLOSED)
-    return;
-
   const base::TimeDelta elapsed_time = clock_->NowTicks() - time_of_last_step_;
 
-  if (elapsed_time < new_tab_opened_timeout_) {
+  if (trigger_state_ == ACTIVE_TAB_CLOSED &&
+      elapsed_time < new_tab_opened_timeout_) {
     tracker_->NotifyEvent(feature_engagement::events::kReopenTabConditionsMet);
-    if (tracker_->ShouldTriggerHelpUI(
-            feature_engagement::kIPHReopenTabFeature)) {
-      DCHECK(cb_);
-      cb_.Run();
-    }
   } else {
     ResetTriggerState();
   }
+
+  // Make sure ShouldTriggerHelpUI is always called when a new tab is
+  // opened. This makes testing the UI easier when the feature engagement demo
+  // mode is enabled (in which the first call always returns true). Making the
+  // call not conditional on our triggering conditions means the UI can be
+  // triggered more easily and consistently. In production, this will always
+  // return false anyway since we didn't call NotifyEvent().
+  if (tracker_->ShouldTriggerHelpUI(feature_engagement::kIPHReopenTabFeature)) {
+    DCHECK(cb_);
+    cb_.Run();
+  }
 }
 
 void ReopenTabInProductHelpTrigger::HelpDismissed() {
diff --git a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc
index 501cffc6..9662356 100644
--- a/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc
+++ b/chrome/browser/ui/in_product_help/reopen_tab_in_product_help_trigger_unittest.cc
@@ -107,7 +107,6 @@
   NiceMock<MockTracker> mock_tracker;
 
   EXPECT_CALL(mock_tracker, NotifyEvent(_)).Times(0);
-  EXPECT_CALL(mock_tracker, ShouldTriggerHelpUI(_)).Times(0);
 
   base::SimpleTestTickClock clock;
   ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock);
@@ -120,7 +119,6 @@
   NiceMock<MockTracker> mock_tracker;
 
   EXPECT_CALL(mock_tracker, NotifyEvent(_)).Times(0);
-  EXPECT_CALL(mock_tracker, ShouldTriggerHelpUI(_)).Times(0);
 
   base::SimpleTestTickClock clock;
   ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock);
@@ -163,3 +161,31 @@
 
   EXPECT_TRUE(triggered);
 }
+
+// Ensures backend's ShouldTriggerHelpUI() is called whenever a new tab is
+// opened, even if we haven't met our triggering conditions yet.
+TEST_F(ReopenTabInProductHelpTriggerTest, AlwaysCallsBackendOnNewTab) {
+  NiceMock<MockTracker> mock_tracker;
+
+  EXPECT_CALL(
+      mock_tracker,
+      NotifyEvent(Eq(feature_engagement::events::kReopenTabConditionsMet)))
+      .Times(0);
+  EXPECT_CALL(mock_tracker, ShouldTriggerHelpUI(_))
+      .Times(2)
+      .WillRepeatedly(Return(false));
+  EXPECT_CALL(mock_tracker, Dismissed(_)).Times(0);
+
+  base::SimpleTestTickClock clock;
+  ReopenTabInProductHelpTrigger reopen_tab_iph(&mock_tracker, &clock);
+
+  reopen_tab_iph.SetShowHelpCallback(
+      base::BindRepeating(DismissImmediately, &reopen_tab_iph));
+
+  // Opening a new tab without closing an active tab first:
+  reopen_tab_iph.NewTabOpened();
+
+  // Opening a new tab after closing a tab too quickly:
+  reopen_tab_iph.ActiveTabClosed(kTabMinimumActiveDuration / 2);
+  reopen_tab_iph.NewTabOpened();
+}
diff --git a/chrome/browser/ui/search/local_ntp_suggestions_browsertest.cc b/chrome/browser/ui/search/local_ntp_suggestions_browsertest.cc
new file mode 100644
index 0000000..3a065ff
--- /dev/null
+++ b/chrome/browser/ui/search/local_ntp_suggestions_browsertest.cc
@@ -0,0 +1,131 @@
+// 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 "base/optional.h"
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/search/ntp_features.h"
+#include "chrome/browser/search/search_suggest/search_suggest_service.h"
+#include "chrome/browser/search/search_suggest/search_suggest_service_factory.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/search/instant_test_utils.h"
+#include "chrome/browser/ui/search/local_ntp_test_utils.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_test_utils.h"
+#include "url/gurl.h"
+
+class MockSearchSuggestService : public SearchSuggestService {
+ public:
+  explicit MockSearchSuggestService(Profile* profile)
+      : SearchSuggestService(profile, nullptr, nullptr) {}
+
+  void Refresh() override {
+    SearchSuggestDataLoaded(SearchSuggestLoader::Status::OK,
+                            search_suggest_data_);
+  }
+
+  void set_search_suggest_data(const SearchSuggestData& search_suggest_data) {
+    search_suggest_data_ = search_suggest_data;
+  }
+
+  const base::Optional<SearchSuggestData>& search_suggest_data()
+      const override {
+    return search_suggest_data_;
+  }
+
+  void SuggestionsDisplayed() override { impression_count_++; };
+
+  int impression_count() { return impression_count_; }
+
+ private:
+  int impression_count_ = 0;
+  base::Optional<SearchSuggestData> search_suggest_data_;
+};
+
+class LocalNTPSearchSuggestTest : public InProcessBrowserTest {
+ protected:
+  LocalNTPSearchSuggestTest() {
+    feature_list_.InitWithFeatures(
+        {features::kUseGoogleLocalNtp, features::kSearchSuggestionsOnLocalNtp},
+        {});
+  }
+
+  MockSearchSuggestService* search_suggest_service() {
+    return static_cast<MockSearchSuggestService*>(
+        SearchSuggestServiceFactory::GetForProfile(browser()->profile()));
+  }
+
+ private:
+  void SetUpInProcessBrowserTestFixture() override {
+    subscription_ =
+        BrowserContextDependencyManager::GetInstance()
+            ->RegisterWillCreateBrowserContextServicesCallbackForTesting(
+                base::BindRepeating(&LocalNTPSearchSuggestTest::
+                                        OnWillCreateBrowserContextServices,
+                                    base::Unretained(this)));
+  }
+
+  static std::unique_ptr<KeyedService> CreateSearchSuggestService(
+      content::BrowserContext* context) {
+    Profile* profile = Profile::FromBrowserContext(context);
+    return std::make_unique<MockSearchSuggestService>(profile);
+  }
+
+  void OnWillCreateBrowserContextServices(content::BrowserContext* context) {
+    SearchSuggestServiceFactory::GetInstance()->SetTestingFactory(
+        context, base::BindRepeating(
+                     &LocalNTPSearchSuggestTest::CreateSearchSuggestService));
+  }
+
+  base::test::ScopedFeatureList feature_list_;
+
+  std::unique_ptr<
+      base::CallbackList<void(content::BrowserContext*)>::Subscription>
+      subscription_;
+};
+
+IN_PROC_BROWSER_TEST_F(LocalNTPSearchSuggestTest, SuggestionsInjectedIntoPage) {
+  EXPECT_EQ(base::nullopt, search_suggest_service()->search_suggest_data());
+
+  SearchSuggestData data;
+  data.suggestions_html = "<div>suggestions</div>";
+  data.end_of_body_script = "console.log('suggestions-done')";
+  search_suggest_service()->set_search_suggest_data(data);
+
+  // Open a new blank tab, then go to NTP and listen for console messages.
+  content::WebContents* active_tab =
+      local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
+  content::ConsoleObserverDelegate console_observer(active_tab,
+                                                    "suggestions-done");
+  active_tab->SetDelegate(&console_observer);
+  local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser(),
+                                                        /*delay=*/1000);
+  console_observer.Wait();
+  EXPECT_EQ("suggestions-done", console_observer.message());
+
+  bool result;
+  ASSERT_TRUE(instant_test_utils::GetBoolFromJS(
+      active_tab, "$('suggestions').innerHTML === '<div>suggestions</div>'",
+      &result));
+  EXPECT_TRUE(result);
+  EXPECT_EQ(1, search_suggest_service()->impression_count());
+}
+
+IN_PROC_BROWSER_TEST_F(LocalNTPSearchSuggestTest, NoSuggestionsjectedIntoPage) {
+  EXPECT_EQ(base::nullopt, search_suggest_service()->search_suggest_data());
+
+  content::WebContents* active_tab =
+      local_ntp_test_utils::OpenNewTab(browser(), GURL("about:blank"));
+  local_ntp_test_utils::NavigateToNTPAndWaitUntilLoaded(browser(),
+                                                        /*delay=*/1000);
+
+  bool result;
+  ASSERT_TRUE(instant_test_utils::GetBoolFromJS(
+      active_tab, "$('suggestions') === null", &result));
+  EXPECT_TRUE(result);
+  EXPECT_EQ(0, search_suggest_service()->impression_count());
+}
diff --git a/chrome/browser/ui/startup/bad_flags_prompt.cc b/chrome/browser/ui/startup/bad_flags_prompt.cc
index e333d942..33125db 100644
--- a/chrome/browser/ui/startup/bad_flags_prompt.cc
+++ b/chrome/browser/ui/startup/bad_flags_prompt.cc
@@ -113,7 +113,7 @@
     // normally with this flag, it is expected that some non-visible operations
     // such as writing user data to disk, cleaning caches, reporting metrics or
     // updating components won't be performed until shutdown.
-    switches::kDisableBackgroundTasks,
+    switches::kDisableBestEffortTasks,
 
     // The UI for Web Bluetooth scanning is not yet implemented. Without the
     // UI websites can scan for bluetooth without user intervention. Show a
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 6c96886..f49e150d 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -118,8 +118,6 @@
 // Returns the appropriate menu label for the IDC_INSTALL_PWA command if
 // available.
 base::Optional<base::string16> GetInstallPWAAppMenuItemName(Browser* browser) {
-  if (!browser->tab_strip_model())
-    return base::nullopt;
   WebContents* web_contents =
       browser->tab_strip_model()->GetActiveWebContents();
   if (!web_contents)
@@ -244,11 +242,12 @@
       uma_action_recorded_(false),
       provider_(provider),
       browser_(browser),
-      app_menu_icon_controller_(app_menu_icon_controller) {}
+      app_menu_icon_controller_(app_menu_icon_controller) {
+  DCHECK(browser_);
+}
 
 AppMenuModel::~AppMenuModel() {
-  if (browser_)  // Null in Cocoa tests.
-    browser_->tab_strip_model()->RemoveObserver(this);
+  browser_->tab_strip_model()->RemoveObserver(this);
 }
 
 void AppMenuModel::Init() {
@@ -890,14 +889,11 @@
 }
 
 void AppMenuModel::UpdateZoomControls() {
-  int zoom_percent = 100;
-  if (browser_->tab_strip_model() &&
-      browser_->tab_strip_model()->GetActiveWebContents()) {
-    zoom_percent = zoom::ZoomController::FromWebContents(
-                       browser_->tab_strip_model()->GetActiveWebContents())
-                       ->GetZoomPercent();
-  }
-  zoom_label_ = base::FormatPercent(zoom_percent);
+  WebContents* contents = browser_->tab_strip_model()->GetActiveWebContents();
+  zoom_label_ = base::FormatPercent(
+      contents
+          ? zoom::ZoomController::FromWebContents(contents)->GetZoomPercent()
+          : 100);
 }
 
 bool AppMenuModel::ShouldShowNewIncognitoWindowMenuItem() {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 6def11e..e45d1ef 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -795,7 +795,7 @@
 
 void BrowserView::UpdateTitleBar() {
   frame_->UpdateWindowTitle();
-  if (!loading_animation_timer_.IsRunning())
+  if (!loading_animation_timer_.IsRunning() && CanChangeWindowIcon())
     frame_->UpdateWindowIcon();
 }
 
@@ -1977,6 +1977,21 @@
     InsertIntoFocusOrderAfter(contents_container_, download_shelf_.get());
 }
 
+bool BrowserView::CanChangeWindowIcon() const {
+  // The logic of this function needs to be same as GetWindowIcon().
+  if (browser_->is_devtools())
+    return false;
+  if (browser_->hosted_app_controller())
+    return true;
+#if defined(OS_CHROMEOS)
+  // On ChromeOS, the tabbed browser always use a static image for the window
+  // icon. See GetWindowIcon().
+  if (browser_->is_type_tabbed())
+    return false;
+#endif
+  return true;
+}
+
 views::View* BrowserView::GetInitiallyFocusedView() {
   return nullptr;
 }
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 61252ddc..e95e89e 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -682,6 +682,11 @@
   // the actual child order.
   void EnsureFocusOrder();
 
+  // Returns true when the window icon of this browser window can change based
+  // on the context. GetWindowIcon() method should return the same image if
+  // this returns false.
+  bool CanChangeWindowIcon() const;
+
   // The BrowserFrame that hosts this view.
   BrowserFrame* frame_ = nullptr;
 
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 0669298..5e884bff 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -862,8 +862,8 @@
 
 OmniboxTint LocationBarView::GetTint() {
   ThemeService* theme_service = ThemeServiceFactory::GetForProfile(profile());
+  bool is_dark_mode = GetNativeTheme()->SystemDarkModeEnabled();
   if (theme_service->UsingDefaultTheme()) {
-    bool is_dark_mode = GetNativeTheme()->SystemDarkModeEnabled();
     return profile()->GetProfileType() == Profile::INCOGNITO_PROFILE ||
                    is_dark_mode
                ? OmniboxTint::DARK
@@ -875,8 +875,7 @@
       theme_service->UsingSystemTheme())
     return OmniboxTint::NATIVE;
 
-  // TODO(tapted): Infer a tint from theme colors?
-  return OmniboxTint::LIGHT;
+  return is_dark_mode ? OmniboxTint::DARK : OmniboxTint::LIGHT;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
index baf039e1..d4a1199b 100644
--- a/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
+++ b/chrome/browser/ui/views/profiles/avatar_toolbar_button.cc
@@ -123,16 +123,21 @@
 
   const SyncState sync_state = GetSyncState();
 
+  if (IsIncognito() && GetThemeProvider()) {
+    color = GetThemeProvider()->GetColor(
+        ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON);
+    // TODO(pbos): Remove this once the incognito chip is always enabled and
+    // triggers a menu.
+    SetTextColor(STATE_DISABLED, *color);
+  }
+
   if (IsIncognitoCounterActive()) {
     const int incognito_window_count =
         BrowserList::GetIncognitoSessionsActiveForProfile(profile_);
-    if (incognito_window_count > 1) {
+    if (incognito_window_count > 1)
       text = base::NumberToString16(incognito_window_count);
-      if (GetThemeProvider()) {
-        color = GetThemeProvider()->GetColor(
-            ThemeProperties::COLOR_TOOLBAR_BUTTON_ICON);
-      }
-    }
+  } else if (IsIncognito()) {
+    text = l10n_util::GetStringUTF16(IDS_AVATAR_BUTTON_INCOGNITO);
   } else if (sync_state == SyncState::kError) {
     color =
         AdjustHighlightColorForContrast(gfx::kGoogleRed300, gfx::kGoogleRed600,
diff --git a/chrome/credential_provider/test/gcp_gls_output_unittest.cc b/chrome/credential_provider/test/gcp_gls_output_unittest.cc
index 0f63e8c..4aad9e0 100644
--- a/chrome/credential_provider/test/gcp_gls_output_unittest.cc
+++ b/chrome/credential_provider/test/gcp_gls_output_unittest.cc
@@ -101,6 +101,9 @@
     : proxy_server_(net::SpawnedTestServer::TYPE_PROXY, base::FilePath()) {}
 
 void GcpUsingChromeTest::SetUp() {
+  if (!ShouldRunTestOnThisOS())
+    return;
+
   // Redirect connections to signin related pages to a handler that will
   // generate the needed headers and content to move the signin flow
   // forward automatically.
@@ -120,6 +123,9 @@
 }
 
 void GcpUsingChromeTest::TearDown() {
+  if (!ShouldRunTestOnThisOS())
+    return;
+
   EXPECT_TRUE(gaia_server_.ShutdownAndWaitUntilComplete());
   EXPECT_TRUE(google_apis_server_.ShutdownAndWaitUntilComplete());
   EXPECT_TRUE(proxy_server_.Stop());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 9bf596a..02570b6 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -973,6 +973,7 @@
       "../browser/ui/search/local_ntp_js_browsertest.cc",
       "../browser/ui/search/local_ntp_one_google_bar_browsertest.cc",
       "../browser/ui/search/local_ntp_promos_browsertest.cc",
+      "../browser/ui/search/local_ntp_suggestions_browsertest.cc",
       "../browser/ui/search/local_ntp_voice_search_browsertest.cc",
       "../browser/ui/search/new_tab_page_navigation_throttle_browsertest.cc",
       "../browser/ui/search_engines/search_engine_tab_helper_browsertest.cc",
diff --git a/chrome/test/chromedriver/BUILD.gn b/chrome/test/chromedriver/BUILD.gn
index fa0b843d..c96498c 100644
--- a/chrome/test/chromedriver/BUILD.gn
+++ b/chrome/test/chromedriver/BUILD.gn
@@ -205,33 +205,6 @@
   ]
 }
 
-action("embed_version_in_cpp") {
-  script = "embed_version_in_cpp.py"
-  inputs = [
-    "cpp_source.py",
-    "VERSION",
-    "//chrome/VERSION",
-
-    # We don't actually use LASTCHANGE as an input file. It is updated
-    # whenever a different Git revision is checked out, at which point
-    # version.cc needs to be updated with the new revision info.
-    lastchange_file,
-  ]
-  outputs = [
-    "$target_gen_dir/version.cc",
-    "$target_gen_dir/version.h",
-  ]
-
-  args = [
-    "--chromedriver-version-file",
-    rebase_path("VERSION", root_build_dir),
-    "--chrome-version-file",
-    rebase_path("//chrome/VERSION", root_build_dir),
-    "--directory",
-    rebase_path(target_gen_dir, root_build_dir),
-  ]
-}
-
 source_set("lib") {
   sources = [
     "//third_party/webdriver/atoms.cc",
@@ -278,6 +251,8 @@
     "session_thread_map.h",
     "util.cc",
     "util.h",
+    "version.cc",
+    "version.h",
     "window_commands.cc",
     "window_commands.h",
   ]
@@ -285,9 +260,6 @@
   # TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
   configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
 
-  # Also compile the generated version files.
-  sources += get_target_outputs(":embed_version_in_cpp")
-
   if (use_x11) {
     sources += [ "keycode_text_conversion_x.cc" ]
   }
@@ -299,11 +271,11 @@
 
   deps = [
     ":automation_client_lib",
-    ":embed_version_in_cpp",
     "//base",
     "//base/third_party/dynamic_annotations",
     "//chrome/common:constants",
     "//chrome/common:version_header",
+    "//components/version_info:generate_version_info",
     "//crypto",
     "//net",
     "//net/server:http_server",
diff --git a/chrome/test/chromedriver/VERSION b/chrome/test/chromedriver/VERSION
deleted file mode 100644
index e72716a7..0000000
--- a/chrome/test/chromedriver/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-2.46
diff --git a/chrome/test/chromedriver/embed_version_in_cpp.py b/chrome/test/chromedriver/embed_version_in_cpp.py
deleted file mode 100755
index 12e515d..0000000
--- a/chrome/test/chromedriver/embed_version_in_cpp.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 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.
-
-"""Embeds version string in C++ code for ChromeDriver."""
-
-import optparse
-import os
-import re
-import sys
-
-import chrome_paths
-import cpp_source
-
-sys.path.insert(0, os.path.join(chrome_paths.GetSrc(), 'build', 'util'))
-import lastchange
-
-
-def get_release_version(chrome_version_file, version_info):
-  """Return version string appropriate for a release branch.
-
-  Args:
-    chrome_version_file: name of Chrome's version file, e.g., chrome/VERSION.
-    version_info: VersionInfo object returned from lastchange.FetchVersionInfo.
-  """
-
-  # Parse Chrome version file, which should have four lines of key=value,
-  # giving the major, minor, build, and patch number.
-  version = {}
-  for line in open(chrome_version_file, 'r').readlines():
-    key, val = line.rstrip('\r\n').split('=', 1)
-    version[key] = val
-
-  if version_info is not None:
-    # Release branch revision has the format
-    # '26c10db8bff36a8b6fc073c0f38b1e9493cabb04-refs/branch-heads/3515@{#5}'.
-    match = re.match('[0-9a-fA-F]+-refs/branch-heads/\d+@{#\d+}',
-                     version_info.revision)
-    if not match:
-      # revision is not the expected format, probably not in a release branch.
-      return None
-
-    # Result is based on Chrome version number, e.g.,
-    # '70.0.3516.0 (26c10db8bff36a8b6fc073c0f38b1e9493cabb04)'.
-    return '%s.%s.%s.%s (%s)' % (
-        version['MAJOR'], version['MINOR'], version['BUILD'], version['PATCH'],
-        version_info.revision_id)
-  else:
-    # No version_info from Git. Assume we are in a release branch if Chrome
-    # patch number is not 0.
-    if version['PATCH'] == '0':
-      return None
-
-    return '%s.%s.%s.%s' % (
-        version['MAJOR'], version['MINOR'], version['BUILD'], version['PATCH'])
-
-
-def get_master_version(chromedriver_version, version_info):
-  """Return version string appropriate for the master branch.
-
-  Args:
-    chromedriver_version: ChromeDriver version, e.g., '2.41'.
-    version_info: VersionInfo object returned from lastchange.FetchVersionInfo.
-  """
-
-  if version_info is None:
-    return None
-
-  # Master branch revision has the format
-  # 'cc009559c91323445dec7e2f545298bf10726eaf-refs/heads/master@{#581331}'.
-  # We need to grab the commit position (e.g., '581331') near the end.
-  match = re.match('[0-9a-fA-F]+-refs/heads/master@{#(\d+)}',
-                   version_info.revision)
-
-  if not match:
-    # revision is not the expected format, probably not in the master branch.
-    return None
-
-  # result is based on legacy style ChromeDriver version number, e.g.,
-  # '2.41.581331 (cc009559c91323445dec7e2f545298bf10726eaf)'.
-  commit_position = match.group(1)
-  return '%s.%s (%s)' % (
-      chromedriver_version, commit_position, version_info.revision_id)
-
-
-def main():
-  parser = optparse.OptionParser()
-  parser.add_option('', '--chromedriver-version-file')
-  parser.add_option('', '--chrome-version-file')
-  parser.add_option(
-      '', '--directory', type='string', default='.',
-      help='Path to directory where the cc/h  file should be created')
-  options, _ = parser.parse_args()
-
-  chromedriver_version = open(
-      options.chromedriver_version_file, 'r').read().strip()
-
-  # Get a VersionInfo object corresponding to the Git commit we are at,
-  # using the same filter used by main function of build/util/lastchange.py.
-  # On success, version_info.revision_id is a 40-digit Git hash,
-  # and version_info.revision is a longer string with more information.
-  # On failure, version_info is None.
-  version_info = lastchange.FetchGitRevision(None, '^Change-Id:')
-
-  version = get_release_version(options.chrome_version_file, version_info)
-
-  if version is None:
-    version = get_master_version(chromedriver_version, version_info)
-
-  if version is None:
-    if version_info is not None:
-      # Not in a known branch, but has Git revision.
-      version = '%s (%s)' % (chromedriver_version, version_info.revision_id)
-    else:
-      # Git command failed. Just use ChromeDriver version string.
-      version = chromedriver_version
-
-  global_string_map = {
-      'kChromeDriverVersion': version
-  }
-  cpp_source.WriteSource('version',
-                         'chrome/test/chromedriver',
-                         options.directory, global_string_map)
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/chrome/test/chromedriver/run_buildbot_steps.py b/chrome/test/chromedriver/run_buildbot_steps.py
index 6d8c1eae..8844b520 100755
--- a/chrome/test/chromedriver/run_buildbot_steps.py
+++ b/chrome/test/chromedriver/run_buildbot_steps.py
@@ -130,12 +130,6 @@
   _PutTestResultsLog(platform, log)
 
 
-def _GetVersion():
-  """Get the current chromedriver version."""
-  with open(os.path.join(_THIS_DIR, 'VERSION'), 'r') as f:
-    return f.read().strip()
-
-
 def _GetSupportedChromeVersions():
   """Get the minimum and maximum supported Chrome versions.
 
@@ -165,8 +159,8 @@
   zip_path = util.Zip(os.path.join(chrome_paths.GetBuildDir([server_name]),
                                    server_name))
 
-  build_name = 'chromedriver_%s_%s.%s.zip' % (
-      platform, _GetVersion(), commit_position)
+  build_name = 'chromedriver_%s_%s.zip' % (
+      platform, commit_position)
   build_url = '%s/%s' % (GS_CONTINUOUS_URL, build_name)
   if slave_utils.GSUtilCopy(zip_path, build_url):
     util.MarkBuildStepError()
@@ -174,8 +168,8 @@
   if util.IsWindows():
     zip_path = util.Zip(os.path.join(
         chrome_paths.GetBuildDir([server_name + '.pdb']), server_name + '.pdb'))
-    pdb_name = 'chromedriver_%s_pdb_%s.%s.zip' % (
-        platform, _GetVersion(), commit_position)
+    pdb_name = 'chromedriver_%s_pdb_%s.zip' % (
+        platform, commit_position)
     pdb_url = '%s/%s' % (GS_CONTINUOUS_URL, pdb_name)
     if slave_utils.GSUtilCopy(zip_path, pdb_url):
       util.MarkBuildStepError()
diff --git a/chrome/test/chromedriver/version.cc b/chrome/test/chromedriver/version.cc
new file mode 100644
index 0000000..ec66dbf
--- /dev/null
+++ b/chrome/test/chromedriver/version.cc
@@ -0,0 +1,8 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/test/chromedriver/version.h"
+#include "components/version_info/version_info_values.h"
+
+const char kChromeDriverVersion[] = PRODUCT_VERSION " (" LAST_CHANGE ")";
diff --git a/chrome/test/chromedriver/version.h b/chrome/test/chromedriver/version.h
new file mode 100644
index 0000000..73195142
--- /dev/null
+++ b/chrome/test/chromedriver/version.h
@@ -0,0 +1,10 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_TEST_CHROMEDRIVER_VERSION_H_
+#define CHROME_TEST_CHROMEDRIVER_VERSION_H_
+
+extern const char kChromeDriverVersion[];
+
+#endif  // CHROME_TEST_CHROMEDRIVER_VERSION_H_
diff --git a/chrome/test/data/webui/welcome/nux_ntp_background_test.js b/chrome/test/data/webui/welcome/nux_ntp_background_test.js
new file mode 100644
index 0000000..22b2f72
--- /dev/null
+++ b/chrome/test/data/webui/welcome/nux_ntp_background_test.js
@@ -0,0 +1,51 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+cr.define('onboarding_ntp_background_test', function() {
+  suite('NuxNtpBackgroundTest', function() {
+    /** @type {!Array<!nux.NtpBackgroundData} */
+    let backgrounds = [
+      {
+        id: 0,
+        title: 'Cat',
+        image_url: 'some/cute/photo/of/a/cat',
+      },
+      {
+        id: 1,
+        title: 'Venice',
+        image_url: 'some/scenic/photo/of/a/beach',
+      },
+    ];
+
+    /** @type {NuxNtpBackgroundElement} */
+    let testElement;
+
+    /** @type {nux.NtpBackgroundProxy} */
+    let testNtpBackgroundProxy;
+
+    setup(function() {
+      testNtpBackgroundProxy = new TestNtpBackgroundProxy();
+      nux.NtpBackgroundProxyImpl.instance_ = testNtpBackgroundProxy;
+      testNtpBackgroundProxy.setBackgroundsList(backgrounds);
+
+      PolymerTest.clearBody();
+      testElement = document.createElement('nux-ntp-background');
+      document.body.appendChild(testElement);
+
+      testElement.onRouteEnter();
+      return Promise.all([
+        testNtpBackgroundProxy.whenCalled('getBackgrounds'),
+      ]);
+    });
+
+    teardown(function() {
+      testElement.remove();
+    });
+
+    test('test placeholder test', function() {
+      // TODO(johntlee): Add actual tests
+      assertTrue(true);
+    });
+  });
+});
diff --git a/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js b/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js
index dd1ffb83..f5146cf 100644
--- a/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js
+++ b/chrome/test/data/webui/welcome/onboarding_welcome_browsertest.js
@@ -154,3 +154,23 @@
 TEST_F('OnboardingWelcomeSetAsDefaultTest', 'All', function() {
   mocha.run();
 });
+
+OnboardingWelcomeNtpBackgroundTest =
+    class extends OnboardingWelcomeBrowserTest {
+  /** @override */
+  get browsePreload() {
+    return 'chrome://welcome/ntp_background/nux_ntp_background.html';
+  }
+
+  /** @override */
+  get extraLibraries() {
+    return super.extraLibraries.concat([
+      'nux_ntp_background_test.js',
+      'test_ntp_background_proxy.js',
+    ]);
+  }
+};
+
+TEST_F('OnboardingWelcomeNtpBackgroundTest', 'All', function() {
+  mocha.run();
+});
diff --git a/chrome/test/data/webui/welcome/test_ntp_background_proxy.js b/chrome/test/data/webui/welcome/test_ntp_background_proxy.js
new file mode 100644
index 0000000..b01d5b0
--- /dev/null
+++ b/chrome/test/data/webui/welcome/test_ntp_background_proxy.js
@@ -0,0 +1,26 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/** @implements {NtpBackgroundProxy} */
+class TestNtpBackgroundProxy extends TestBrowserProxy {
+  constructor() {
+    super([
+      'getBackgrounds',
+    ]);
+
+    /** @private {!Array<!nux.NtpBackgroundData} */
+    this.backgroundsList_ = [];
+  }
+
+  /** @override */
+  getBackgrounds() {
+    this.methodCalled('getBackgrounds');
+    return Promise.resolve(this.backgroundsList_);
+  }
+
+  /** @param {!Array<!nux.NtpBackgroundData>} backgroundsList */
+  setBackgroundsList(backgroundsList) {
+    this.backgroundsList_ = backgroundsList;
+  }
+}
diff --git a/chrome/test/data/xr/e2e_test_files/html/test_webxr_poses.html b/chrome/test/data/xr/e2e_test_files/html/test_webxr_poses.html
index 2da68b6..9e02b4c 100644
--- a/chrome/test/data/xr/e2e_test_files/html/test_webxr_poses.html
+++ b/chrome/test/data/xr/e2e_test_files/html/test_webxr_poses.html
@@ -43,7 +43,7 @@
       function checkFrameView(frame_id, eye, expected) {
         let frame_data = frame_data_array[frame_id];
         let pose = frame_data.getViewerPose(cached_frame_of_ref);
-        return MatrixCompare(pose.getViewMatrix(frame_data_array[frame_id].views[eye]), expected);
+        return MatrixCompare(pose.views[eye].viewMatrix, expected);
       }
 
       function checkFramePose(frame_id, expected) {
@@ -57,8 +57,8 @@
           return true;
         }
 
-        console.log("checkFramePose: " + pose.poseModelMatrix + "\n" + expected);
-        return MatrixCompare(pose.poseModelMatrix, expected);
+        console.log("checkFramePose: " + pose.transform.matrix + "\n" + expected);
+        return MatrixCompare(pose.transform.matrix, expected);
       }
 
       onImmersiveXRFrameCallback = function(session, frame, gl) {
diff --git a/chromeos/components/drivefs/drivefs_bootstrap.cc b/chromeos/components/drivefs/drivefs_bootstrap.cc
index 7a5dbf6..a847aea 100644
--- a/chromeos/components/drivefs/drivefs_bootstrap.cc
+++ b/chromeos/components/drivefs/drivefs_bootstrap.cc
@@ -69,18 +69,12 @@
       &DriveFsConnection::OnMojoConnectionError, base::Unretained(this)));
 }
 
-DriveFsConnection::~DriveFsConnection() {
-  CleanUp();
-}
+DriveFsConnection::~DriveFsConnection() = default;
 
-void DriveFsConnection::CleanUp() {
+void DriveFsConnection::OnMojoConnectionError() {
   if (on_disconnected_ && bootstrap_listener_->is_connected()) {
     std::move(on_disconnected_).Run();
   }
 }
 
-void DriveFsConnection::OnMojoConnectionError() {
-  CleanUp();
-}
-
 }  // namespace drivefs
diff --git a/chromeos/components/drivefs/drivefs_bootstrap.h b/chromeos/components/drivefs/drivefs_bootstrap.h
index 790c4b6..2cf511f 100644
--- a/chromeos/components/drivefs/drivefs_bootstrap.h
+++ b/chromeos/components/drivefs/drivefs_bootstrap.h
@@ -63,7 +63,6 @@
   mojom::DriveFs* drivefs_interface() const { return drivefs_.get(); }
 
  private:
-  void CleanUp();
   void OnMojoConnectionError();
 
   std::unique_ptr<DriveFsBootstrapListener> bootstrap_listener_;
diff --git a/chromeos/components/drivefs/drivefs_bootstrap_unittest.cc b/chromeos/components/drivefs/drivefs_bootstrap_unittest.cc
index fb505fdc..62c2ff5 100644
--- a/chromeos/components/drivefs/drivefs_bootstrap_unittest.cc
+++ b/chromeos/components/drivefs/drivefs_bootstrap_unittest.cc
@@ -137,7 +137,7 @@
   auto token = ListenForConnection();
   EXPECT_CALL(*this, OnInit());
   WaitForConnection(token);
-  EXPECT_CALL(*this, OnDisconnect());
+  EXPECT_CALL(*this, OnDisconnect()).Times(0);
   connection_.reset();
   base::RunLoop().RunUntilIdle();
   ASSERT_FALSE(
diff --git a/chromeos/components/drivefs/drivefs_host_unittest.cc b/chromeos/components/drivefs/drivefs_host_unittest.cc
index 9157482..b3fd27f 100644
--- a/chromeos/components/drivefs/drivefs_host_unittest.cc
+++ b/chromeos/components/drivefs/drivefs_host_unittest.cc
@@ -371,6 +371,7 @@
   }
 
   void DoUnmount() {
+    EXPECT_CALL(*host_delegate_, OnUnmounted(_)).Times(0);
     host_->Unmount();
     binding_.Unbind();
     bootstrap_binding_.Unbind();
diff --git a/chromeos/constants/chromeos_switches.cc b/chromeos/constants/chromeos_switches.cc
index d078b1a8..e1d3d8a 100644
--- a/chromeos/constants/chromeos_switches.cc
+++ b/chromeos/constants/chromeos_switches.cc
@@ -49,6 +49,9 @@
 const base::Feature kShowPlayInDemoMode{"ShowPlayInDemoMode",
                                         base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kShowSplashScreenInDemoMode{
+    "ShowSplashScreenInDemoMode", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Please keep the order of these switches synchronized with the header file
 // (i.e. in alphabetical order).
 
diff --git a/chromeos/constants/chromeos_switches.h b/chromeos/constants/chromeos_switches.h
index 24660246..96c7e2f 100644
--- a/chromeos/constants/chromeos_switches.h
+++ b/chromeos/constants/chromeos_switches.h
@@ -163,6 +163,10 @@
 // Controls whether to show the Play Store icon in Demo Mode.
 CHROMEOS_EXPORT extern const base::Feature kShowPlayInDemoMode;
 
+// Controls whether to show a static splash screen instead of the user pods
+// before demo sessions log in.
+CHROMEOS_EXPORT extern const base::Feature kShowSplashScreenInDemoMode;
+
 // Returns true if the system should wake in response to wifi traffic.
 CHROMEOS_EXPORT bool WakeOnWifiEnabled();
 
diff --git a/chromeos/dbus/cicerone_client.cc b/chromeos/dbus/cicerone_client.cc
index c2bf9cd..cff917b 100644
--- a/chromeos/dbus/cicerone_client.cc
+++ b/chromeos/dbus/cicerone_client.cc
@@ -153,31 +153,6 @@
                        weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
-  void GetLinuxPackageInfoFromApt(
-      const vm_tools::cicerone::LinuxPackageInfoFromAptRequest& request,
-      DBusMethodCallback<vm_tools::cicerone::LinuxPackageInfoResponse> callback)
-      override {
-    dbus::MethodCall method_call(
-        vm_tools::cicerone::kVmCiceroneInterface,
-        vm_tools::cicerone::kGetLinuxPackageInfoFromAptMethod);
-    dbus::MessageWriter writer(&method_call);
-
-    if (!writer.AppendProtoAsArrayOfBytes(request)) {
-      LOG(ERROR)
-          << "Failed to encode GetLinuxPackageInfoFromAptRequest protobuf";
-      base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
-
-      return;
-    }
-
-    cicerone_proxy_->CallMethod(
-        &method_call, kDefaultTimeout.InMilliseconds(),
-        base::BindOnce(&CiceroneClientImpl::OnDBusProtoResponse<
-                           vm_tools::cicerone::LinuxPackageInfoResponse>,
-                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-  }
-
   void InstallLinuxPackage(
       const vm_tools::cicerone::InstallLinuxPackageRequest& request,
       DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
@@ -201,30 +176,6 @@
                        weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
-  void InstallLinuxPackageFromApt(
-      const vm_tools::cicerone::InstallLinuxPackageFromAptRequest& request,
-      DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
-          callback) override {
-    dbus::MethodCall method_call(
-        vm_tools::cicerone::kVmCiceroneInterface,
-        vm_tools::cicerone::kInstallLinuxPackageFromAptMethod);
-    dbus::MessageWriter writer(&method_call);
-
-    if (!writer.AppendProtoAsArrayOfBytes(request)) {
-      LOG(ERROR)
-          << "Failed to encode InstallLinuxPackageFromAptRequest protobuf";
-      base::ThreadTaskRunnerHandle::Get()->PostTask(
-          FROM_HERE, base::BindOnce(std::move(callback), base::nullopt));
-      return;
-    }
-
-    cicerone_proxy_->CallMethod(
-        &method_call, kDefaultTimeout.InMilliseconds(),
-        base::BindOnce(&CiceroneClientImpl::OnDBusProtoResponse<
-                           vm_tools::cicerone::InstallLinuxPackageResponse>,
-                       weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-  }
-
   void UninstallPackageOwningFile(
       const vm_tools::cicerone::UninstallPackageOwningFileRequest& request,
       DBusMethodCallback<vm_tools::cicerone::UninstallPackageOwningFileResponse>
diff --git a/chromeos/dbus/cicerone_client.h b/chromeos/dbus/cicerone_client.h
index c645100..7fd0721 100644
--- a/chromeos/dbus/cicerone_client.h
+++ b/chromeos/dbus/cicerone_client.h
@@ -141,14 +141,6 @@
       DBusMethodCallback<vm_tools::cicerone::LinuxPackageInfoResponse>
           callback) = 0;
 
-  // Gets information about a Linux package via it's name from an APT
-  // repository inside a container. |callback| is called after the method
-  // call finishes.
-  virtual void GetLinuxPackageInfoFromApt(
-      const vm_tools::cicerone::LinuxPackageInfoFromAptRequest& request,
-      DBusMethodCallback<vm_tools::cicerone::LinuxPackageInfoResponse>
-          callback) = 0;
-
   // Installs a package inside the container.
   // |callback| is called after the method call finishes.
   virtual void InstallLinuxPackage(
@@ -156,13 +148,6 @@
       DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
           callback) = 0;
 
-  // Installs a package inside the container from an APT repository using a
-  // package_id. |callback| is called after the method call finishes.
-  virtual void InstallLinuxPackageFromApt(
-      const vm_tools::cicerone::InstallLinuxPackageFromAptRequest& request,
-      DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
-          callback) = 0;
-
   // Uninstalls the package that owns the indicated .desktop file.
   // |callback| is called after the method call finishes.
   virtual void UninstallPackageOwningFile(
diff --git a/chromeos/dbus/fake_cicerone_client.cc b/chromeos/dbus/fake_cicerone_client.cc
index 5510936..b672f8c 100644
--- a/chromeos/dbus/fake_cicerone_client.cc
+++ b/chromeos/dbus/fake_cicerone_client.cc
@@ -119,14 +119,6 @@
       base::BindOnce(std::move(callback), get_linux_package_info_response_));
 }
 
-void FakeCiceroneClient::GetLinuxPackageInfoFromApt(
-    const vm_tools::cicerone::LinuxPackageInfoFromAptRequest& request,
-    DBusMethodCallback<vm_tools::cicerone::LinuxPackageInfoResponse> callback) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(std::move(callback), get_linux_package_info_response_));
-}
-
 void FakeCiceroneClient::InstallLinuxPackage(
     const vm_tools::cicerone::InstallLinuxPackageRequest& request,
     DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
@@ -136,15 +128,6 @@
       base::BindOnce(std::move(callback), install_linux_package_response_));
 }
 
-void FakeCiceroneClient::InstallLinuxPackageFromApt(
-    const vm_tools::cicerone::InstallLinuxPackageFromAptRequest& request,
-    DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
-        callback) {
-  base::ThreadTaskRunnerHandle::Get()->PostTask(
-      FROM_HERE,
-      base::BindOnce(std::move(callback), install_linux_package_response_));
-}
-
 void FakeCiceroneClient::UninstallPackageOwningFile(
     const vm_tools::cicerone::UninstallPackageOwningFileRequest& request,
     DBusMethodCallback<vm_tools::cicerone::UninstallPackageOwningFileResponse>
diff --git a/chromeos/dbus/fake_cicerone_client.h b/chromeos/dbus/fake_cicerone_client.h
index 941dd5a..4454cea 100644
--- a/chromeos/dbus/fake_cicerone_client.h
+++ b/chromeos/dbus/fake_cicerone_client.h
@@ -78,14 +78,6 @@
       DBusMethodCallback<vm_tools::cicerone::LinuxPackageInfoResponse> callback)
       override;
 
-  // Fake version of the method that gets information about a Linux package via
-  // its name, inside a Container. |callback| is called after the method call
-  // finishes.
-  void GetLinuxPackageInfoFromApt(
-      const vm_tools::cicerone::LinuxPackageInfoFromAptRequest& request,
-      DBusMethodCallback<vm_tools::cicerone::LinuxPackageInfoResponse> callback)
-      override;
-
   // Fake version of the method that installs an application inside a running
   // Container. |callback| is called after the method call finishes. This does
   // not cause progress events to be fired.
@@ -94,14 +86,6 @@
       DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
           callback) override;
 
-  // Fake version of the method that installs an application inside a running
-  // Container. |callback| is called after the method call finishes. This does
-  // not cause progress events to be fired.
-  void InstallLinuxPackageFromApt(
-      const vm_tools::cicerone::InstallLinuxPackageFromAptRequest& request,
-      DBusMethodCallback<vm_tools::cicerone::InstallLinuxPackageResponse>
-          callback) override;
-
   // Fake version of the method that uninstalls an application inside a running
   // Container. |callback| is called after the method call finishes. This does
   // not cause progress events to be fired.
@@ -275,11 +259,6 @@
     setup_lxd_container_user_response_ = setup_lxd_container_user_response;
   }
 
-  void set_search_app_response(
-      const vm_tools::cicerone::AppSearchResponse& search_app_response) {
-    search_app_response_ = search_app_response;
-  }
-
   void set_export_lxd_container_response(
       const vm_tools::cicerone::ExportLxdContainerResponse&
           export_lxd_container_response) {
diff --git a/chromeos/services/assistant/BUILD.gn b/chromeos/services/assistant/BUILD.gn
index 8314087..d38e7f7 100644
--- a/chromeos/services/assistant/BUILD.gn
+++ b/chromeos/services/assistant/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//chromeos/assistant/assistant.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 assert(is_chromeos)
 assert(enable_cros_assistant)
@@ -114,11 +113,6 @@
   }
 }
 
-service_manifest("manifest") {
-  name = "assistant"
-  source = "manifest.json"
-}
-
 source_set("tests") {
   testonly = true
   deps = [
diff --git a/chromeos/services/assistant/OWNERS b/chromeos/services/assistant/OWNERS
index 03ef6f4..1f575b1 100644
--- a/chromeos/services/assistant/OWNERS
+++ b/chromeos/services/assistant/OWNERS
@@ -1,6 +1,3 @@
 file://chromeos/assistant/OWNERS
 
 # COMPONENTS: UI>Shell>Assistant
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/assistant/audio_decoder/BUILD.gn b/chromeos/services/assistant/audio_decoder/BUILD.gn
index 6c6a3bf7..5417ed0b 100644
--- a/chromeos/services/assistant/audio_decoder/BUILD.gn
+++ b/chromeos/services/assistant/audio_decoder/BUILD.gn
@@ -4,8 +4,6 @@
 
 import("//chromeos/assistant/assistant.gni")
 
-import("//services/service_manager/public/service_manifest.gni")
-
 assert(enable_cros_libassistant)
 
 source_set("lib") {
@@ -31,8 +29,3 @@
     "//services/service_manager/public/cpp:cpp",
   ]
 }
-
-service_manifest("manifest") {
-  name = "assistant_audio_decoder"
-  source = "manifest.json"
-}
diff --git a/chromeos/services/assistant/audio_decoder/OWNERS b/chromeos/services/assistant/audio_decoder/OWNERS
index 59dfd4b3..e69de29 100644
--- a/chromeos/services/assistant/audio_decoder/OWNERS
+++ b/chromeos/services/assistant/audio_decoder/OWNERS
@@ -1,2 +0,0 @@
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/assistant/audio_decoder/manifest.json b/chromeos/services/assistant/audio_decoder/manifest.json
deleted file mode 100644
index 0cf436f3..0000000
--- a/chromeos/services/assistant/audio_decoder/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "name": "assistant_audio_decoder",
-  "display_name": "Assistant Audio Decoder Service",
-  "sandbox_type": "utility",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "assistant:audio_decoder": [ "chromeos.assistant.mojom.AssistantAudioDecoderFactory" ]
-      }
-    }
-  }
-}
diff --git a/chromeos/services/assistant/manifest.json b/chromeos/services/assistant/manifest.json
deleted file mode 100644
index cc94176..0000000
--- a/chromeos/services/assistant/manifest.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  "name": "assistant",
-  "display_name": "Assistant Service",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "requires": {
-        "ash": [ "system_ui" ],
-        "assistant_audio_decoder": [ "assistant:audio_decoder" ],
-        "audio": [ "stream_factory" ],
-        "device": [ "device:battery_monitor" ],
-        "identity": [ "identity_manager" ],
-        "media_session": [ "app" ]
-      },
-      "provides": {
-        "assistant": [
-            "chromeos.assistant.mojom.Assistant",
-            "chromeos.assistant.mojom.AssistantPlatform",
-            "chromeos.assistant.mojom.AssistantSettingsManager"
-        ]
-      }
-    }
-  }
-}
diff --git a/chromeos/services/assistant/public/cpp/BUILD.gn b/chromeos/services/assistant/public/cpp/BUILD.gn
new file mode 100644
index 0000000..3ed32ec
--- /dev/null
+++ b/chromeos/services/assistant/public/cpp/BUILD.gn
@@ -0,0 +1,29 @@
+# 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.
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromeos/services/assistant/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
+
+source_set("audio_decoder_manifest") {
+  sources = [
+    "audio_decoder_manifest.cc",
+    "audio_decoder_manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromeos/services/assistant/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/chromeos/services/assistant/public/cpp/OWNERS b/chromeos/services/assistant/public/cpp/OWNERS
new file mode 100644
index 0000000..e41ac9e
--- /dev/null
+++ b/chromeos/services/assistant/public/cpp/OWNERS
@@ -0,0 +1,8 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
+per-file audio_decoder_manifest.cc=set noparent
+per-file audio_decoder_manifest.cc=file://ipc/SECURITY_OWNERS
+per-file audio_decoder_manifest.h=set noparent
+per-file audio_decoder_manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/assistant/public/cpp/audio_decoder_manifest.cc b/chromeos/services/assistant/public/cpp/audio_decoder_manifest.cc
new file mode 100644
index 0000000..4c6570e
--- /dev/null
+++ b/chromeos/services/assistant/public/cpp/audio_decoder_manifest.cc
@@ -0,0 +1,34 @@
+// 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/services/assistant/public/cpp/audio_decoder_manifest.h"
+
+#include "base/no_destructor.h"
+#include "chromeos/services/assistant/public/mojom/assistant_audio_decoder.mojom.h"
+#include "chromeos/services/assistant/public/mojom/constants.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace chromeos {
+namespace assistant {
+
+const service_manager::Manifest& GetAudioDecoderManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kAudioDecoderServiceName)
+          .WithDisplayName("Assistant Audio Decoder Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("utility")
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability("assistant:audio_decoder",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::AssistantAudioDecoderFactory>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace assistant
+}  // namespace chromeos
diff --git a/chromeos/services/assistant/public/cpp/audio_decoder_manifest.h b/chromeos/services/assistant/public/cpp/audio_decoder_manifest.h
new file mode 100644
index 0000000..3affafd
--- /dev/null
+++ b/chromeos/services/assistant/public/cpp/audio_decoder_manifest.h
@@ -0,0 +1,18 @@
+// 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_SERVICES_ASSISTANT_PUBLIC_CPP_AUDIO_DECODER_MANIFEST_H_
+#define CHROMEOS_SERVICES_ASSISTANT_PUBLIC_CPP_AUDIO_DECODER_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace chromeos {
+namespace assistant {
+
+const service_manager::Manifest& GetAudioDecoderManifest();
+
+}  // namespace assistant
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_ASSISTANT_PUBLIC_CPP_AUDIO_DECODER_MANIFEST_H_
diff --git a/chromeos/services/assistant/public/cpp/manifest.cc b/chromeos/services/assistant/public/cpp/manifest.cc
new file mode 100644
index 0000000..5ac6780
--- /dev/null
+++ b/chromeos/services/assistant/public/cpp/manifest.cc
@@ -0,0 +1,39 @@
+// 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/services/assistant/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "chromeos/services/assistant/public/mojom/assistant.mojom.h"
+#include "chromeos/services/assistant/public/mojom/constants.mojom.h"
+#include "chromeos/services/assistant/public/mojom/settings.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace chromeos {
+namespace assistant {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Assistant Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder().Build())
+          .ExposeCapability("assistant",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::Assistant, mojom::AssistantPlatform,
+                                mojom::AssistantSettingsManager>())
+          .RequireCapability("ash", "system_ui")
+          .RequireCapability("assistant_audio_decoder",
+                             "assistant:audio_decoder")
+          .RequireCapability("audio", "stream_factory")
+          .RequireCapability("device", "device:battery_monitor")
+          .RequireCapability("identity", "identity_manager")
+          .RequireCapability("media_session", "app")
+
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace assistant
+}  // namespace chromeos
diff --git a/chromeos/services/assistant/public/cpp/manifest.h b/chromeos/services/assistant/public/cpp/manifest.h
new file mode 100644
index 0000000..81b48b2
--- /dev/null
+++ b/chromeos/services/assistant/public/cpp/manifest.h
@@ -0,0 +1,18 @@
+// 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_SERVICES_ASSISTANT_PUBLIC_CPP_MANIFEST_H_
+#define CHROMEOS_SERVICES_ASSISTANT_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace chromeos {
+namespace assistant {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace assistant
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_ASSISTANT_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromeos/services/device_sync/BUILD.gn b/chromeos/services/device_sync/BUILD.gn
index 98b37b5..63ed06a9 100644
--- a/chromeos/services/device_sync/BUILD.gn
+++ b/chromeos/services/device_sync/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
 
 static_library("device_sync") {
@@ -106,11 +104,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "device_sync"
-  source = "manifest.json"
-}
-
 static_library("test_support") {
   testonly = true
 
diff --git a/chromeos/services/device_sync/OWNERS b/chromeos/services/device_sync/OWNERS
index 271c028..3bcc51b9 100644
--- a/chromeos/services/device_sync/OWNERS
+++ b/chromeos/services/device_sync/OWNERS
@@ -1,7 +1,5 @@
 file://chromeos/components/multidevice/OWNERS
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 per-file *_type_converter*.*=set noparent
 per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
 
diff --git a/chromeos/services/device_sync/manifest.json b/chromeos/services/device_sync/manifest.json
deleted file mode 100644
index 2cb19ac..0000000
--- a/chromeos/services/device_sync/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "device_sync",
-  "display_name": "DeviceSync Service",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "device_sync": [ "chromeos.device_sync.mojom.DeviceSync" ]
-      },
-      "requires": {
-        "preferences": [ "pref_client" ]
-      }
-    }
-  }
-}
diff --git a/chromeos/services/device_sync/public/cpp/BUILD.gn b/chromeos/services/device_sync/public/cpp/BUILD.gn
index ca926ff..fe4b0c3 100644
--- a/chromeos/services/device_sync/public/cpp/BUILD.gn
+++ b/chromeos/services/device_sync/public/cpp/BUILD.gn
@@ -68,3 +68,17 @@
     "//testing/gtest",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromeos/services/device_sync/public/mojom",
+    "//services/preferences/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/chromeos/services/device_sync/public/cpp/OWNERS b/chromeos/services/device_sync/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/chromeos/services/device_sync/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/device_sync/public/cpp/manifest.cc b/chromeos/services/device_sync/public/cpp/manifest.cc
new file mode 100644
index 0000000..d2cdfa7
--- /dev/null
+++ b/chromeos/services/device_sync/public/cpp/manifest.cc
@@ -0,0 +1,30 @@
+// 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/services/device_sync/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "chromeos/services/device_sync/public/mojom/constants.mojom.h"
+#include "chromeos/services/device_sync/public/mojom/device_sync.mojom.h"
+#include "services/preferences/public/mojom/preferences.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace chromeos {
+namespace device_sync {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("DeviceSync Service")
+          .ExposeCapability(
+              "device_sync",
+              service_manager::Manifest::InterfaceList<mojom::DeviceSync>())
+          .RequireCapability(prefs::mojom::kServiceName, "pref_client")
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace device_sync
+}  // namespace chromeos
diff --git a/chromeos/services/device_sync/public/cpp/manifest.h b/chromeos/services/device_sync/public/cpp/manifest.h
new file mode 100644
index 0000000..404c165
--- /dev/null
+++ b/chromeos/services/device_sync/public/cpp/manifest.h
@@ -0,0 +1,18 @@
+// 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_SERVICES_DEVICE_SYNC_PUBLIC_CPP_MANIFEST_H_
+#define CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace chromeos {
+namespace device_sync {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace device_sync
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_DEVICE_SYNC_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromeos/services/ime/BUILD.gn b/chromeos/services/ime/BUILD.gn
index 796744b..989102a 100644
--- a/chromeos/services/ime/BUILD.gn
+++ b/chromeos/services/ime/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//chromeos/services/ime/public/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
 
@@ -45,11 +44,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "ime"
-  source = "manifest.json"
-}
-
 source_set("unit_tests") {
   testonly = true
   deps = [
diff --git a/chromeos/services/ime/OWNERS b/chromeos/services/ime/OWNERS
index ce6792f..b71b379 100644
--- a/chromeos/services/ime/OWNERS
+++ b/chromeos/services/ime/OWNERS
@@ -1,7 +1,5 @@
 googleo@chromium.org
 shuchen@chromium.org
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 
 per-file ime_sandbox_hook.*=file://sandbox/linux/OWNERS
diff --git a/chromeos/services/ime/manifest.json b/chromeos/services/ime/manifest.json
deleted file mode 100644
index e0d54c3..0000000
--- a/chromeos/services/ime/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "ime",
-  "display_name": "IME",
-  "sandbox_type": "utility",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "input_engine" : [
-          "chromeos.ime.mojom.InputEngineManager",
-          "chromeos.ime.mojom.InputChannel"
-        ]
-      }
-    }
-  }
-}
diff --git a/chromeos/services/ime/public/cpp/BUILD.gn b/chromeos/services/ime/public/cpp/BUILD.gn
index 0a8d020..c8c17bf2 100644
--- a/chromeos/services/ime/public/cpp/BUILD.gn
+++ b/chromeos/services/ime/public/cpp/BUILD.gn
@@ -106,3 +106,16 @@
     "rulebased/rulebased_unittest.cc",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromeos/services/ime/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/chromeos/services/ime/public/cpp/OWNERS b/chromeos/services/ime/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/chromeos/services/ime/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/ime/public/cpp/manifest.cc b/chromeos/services/ime/public/cpp/manifest.cc
new file mode 100644
index 0000000..5096e1e
--- /dev/null
+++ b/chromeos/services/ime/public/cpp/manifest.cc
@@ -0,0 +1,35 @@
+// 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/services/ime/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "chromeos/services/ime/public/mojom/constants.mojom.h"
+#include "chromeos/services/ime/public/mojom/input_engine.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace chromeos {
+namespace ime {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("IME")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("utility")
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability(
+              "input_engine",
+              service_manager::Manifest::InterfaceList<
+                  mojom::InputEngineManager, mojom::InputChannel>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace ime
+}  // namespace chromeos
diff --git a/chromeos/services/ime/public/cpp/manifest.h b/chromeos/services/ime/public/cpp/manifest.h
new file mode 100644
index 0000000..dedb240
--- /dev/null
+++ b/chromeos/services/ime/public/cpp/manifest.h
@@ -0,0 +1,18 @@
+// 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_SERVICES_IME_PUBLIC_CPP_MANIFEST_H_
+#define CHROMEOS_SERVICES_IME_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace chromeos {
+namespace ime {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace ime
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_IME_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromeos/services/multidevice_setup/BUILD.gn b/chromeos/services/multidevice_setup/BUILD.gn
index 326660f..256bdf6 100644
--- a/chromeos/services/multidevice_setup/BUILD.gn
+++ b/chromeos/services/multidevice_setup/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
 
 static_library("multidevice_setup") {
@@ -83,11 +81,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "multidevice_setup"
-  source = "manifest.json"
-}
-
 static_library("test_support") {
   testonly = true
 
diff --git a/chromeos/services/multidevice_setup/OWNERS b/chromeos/services/multidevice_setup/OWNERS
index 2e89025..029c08c 100644
--- a/chromeos/services/multidevice_setup/OWNERS
+++ b/chromeos/services/multidevice_setup/OWNERS
@@ -1,6 +1,4 @@
 file://chromeos/components/multidevice/OWNERS
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 
 # COMPONENT: UI>Multidevice
diff --git a/chromeos/services/multidevice_setup/manifest.json b/chromeos/services/multidevice_setup/manifest.json
deleted file mode 100644
index b2014e4..0000000
--- a/chromeos/services/multidevice_setup/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "multidevice_setup",
-  "display_name": "MultiDevice Setup Service",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "multidevice_setup" : [
-          "chromeos.multidevice_setup.mojom.MultiDeviceSetup",
-          "chromeos.multidevice_setup.mojom.PrivilegedHostDeviceSetter"
-        ]
-      }
-    }
-  }
-}
diff --git a/chromeos/services/multidevice_setup/public/cpp/BUILD.gn b/chromeos/services/multidevice_setup/public/cpp/BUILD.gn
index d26bd575..835cd92 100644
--- a/chromeos/services/multidevice_setup/public/cpp/BUILD.gn
+++ b/chromeos/services/multidevice_setup/public/cpp/BUILD.gn
@@ -155,3 +155,16 @@
     "//testing/gtest",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromeos/services/multidevice_setup/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/chromeos/services/multidevice_setup/public/cpp/OWNERS b/chromeos/services/multidevice_setup/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/chromeos/services/multidevice_setup/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/multidevice_setup/public/cpp/manifest.cc b/chromeos/services/multidevice_setup/public/cpp/manifest.cc
new file mode 100644
index 0000000..e258871
--- /dev/null
+++ b/chromeos/services/multidevice_setup/public/cpp/manifest.cc
@@ -0,0 +1,30 @@
+// 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/services/multidevice_setup/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "chromeos/services/multidevice_setup/public/mojom/constants.mojom.h"
+#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace chromeos {
+namespace multidevice_setup {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("MultiDevice Setup Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder().Build())
+          .ExposeCapability(
+              "multidevice_setup",
+              service_manager::Manifest::InterfaceList<
+                  mojom::MultiDeviceSetup, mojom::PrivilegedHostDeviceSetter>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace multidevice_setup
+}  // namespace chromeos
diff --git a/chromeos/services/multidevice_setup/public/cpp/manifest.h b/chromeos/services/multidevice_setup/public/cpp/manifest.h
new file mode 100644
index 0000000..ee3438c
--- /dev/null
+++ b/chromeos/services/multidevice_setup/public/cpp/manifest.h
@@ -0,0 +1,18 @@
+// 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_SERVICES_MULTIDEVICE_SETUP_PUBLIC_CPP_MANIFEST_H_
+#define CHROMEOS_SERVICES_MULTIDEVICE_SETUP_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace chromeos {
+namespace multidevice_setup {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace multidevice_setup
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_MULTIDEVICE_SETUP_PUBLIC_CPP_MANIFEST_H_
diff --git a/chromeos/services/secure_channel/BUILD.gn b/chromeos/services/secure_channel/BUILD.gn
index 7c66b2b..1aa62e7 100644
--- a/chromeos/services/secure_channel/BUILD.gn
+++ b/chromeos/services/secure_channel/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 assert(is_chromeos, "Non-ChromeOS builds cannot depend on //chromeos")
 
 static_library("secure_channel") {
@@ -174,11 +172,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "secure_channel"
-  source = "manifest.json"
-}
-
 static_library("test_support") {
   testonly = true
 
diff --git a/chromeos/services/secure_channel/OWNERS b/chromeos/services/secure_channel/OWNERS
index 2e89025..029c08c 100644
--- a/chromeos/services/secure_channel/OWNERS
+++ b/chromeos/services/secure_channel/OWNERS
@@ -1,6 +1,4 @@
 file://chromeos/components/multidevice/OWNERS
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 
 # COMPONENT: UI>Multidevice
diff --git a/chromeos/services/secure_channel/manifest.json b/chromeos/services/secure_channel/manifest.json
deleted file mode 100644
index a907c11..0000000
--- a/chromeos/services/secure_channel/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "secure_channel",
-  "display_name": "SecureChannel Service",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "secure_channel": [ "chromeos.secure_channel.mojom.SecureChannel" ]
-       }
-     }
-  }
-}
diff --git a/chromeos/services/secure_channel/public/cpp/BUILD.gn b/chromeos/services/secure_channel/public/cpp/BUILD.gn
new file mode 100644
index 0000000..86f43e6
--- /dev/null
+++ b/chromeos/services/secure_channel/public/cpp/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//chromeos/services/secure_channel/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/chromeos/services/secure_channel/public/cpp/OWNERS b/chromeos/services/secure_channel/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/chromeos/services/secure_channel/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/chromeos/services/secure_channel/public/cpp/manifest.cc b/chromeos/services/secure_channel/public/cpp/manifest.cc
new file mode 100644
index 0000000..6238574
--- /dev/null
+++ b/chromeos/services/secure_channel/public/cpp/manifest.cc
@@ -0,0 +1,33 @@
+// 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/services/secure_channel/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "chromeos/services/secure_channel/public/mojom/constants.mojom.h"
+#include "chromeos/services/secure_channel/public/mojom/secure_channel.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace chromeos {
+namespace secure_channel {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("SecureChannel Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability(
+              "secure_channel",
+              service_manager::Manifest::InterfaceList<mojom::SecureChannel>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace secure_channel
+}  // namespace chromeos
diff --git a/chromeos/services/secure_channel/public/cpp/manifest.h b/chromeos/services/secure_channel/public/cpp/manifest.h
new file mode 100644
index 0000000..a64701f
--- /dev/null
+++ b/chromeos/services/secure_channel/public/cpp/manifest.h
@@ -0,0 +1,18 @@
+// 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_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_MANIFEST_H_
+#define CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace chromeos {
+namespace secure_channel {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace secure_channel
+}  // namespace chromeos
+
+#endif  // CHROMEOS_SERVICES_SECURE_CHANNEL_PUBLIC_CPP_MANIFEST_H_
diff --git a/components/cast_channel/cast_socket_unittest.cc b/components/cast_channel/cast_socket_unittest.cc
index adf7686..60a7a78 100644
--- a/components/cast_channel/cast_socket_unittest.cc
+++ b/components/cast_channel/cast_socket_unittest.cc
@@ -372,6 +372,21 @@
     NOTIMPLEMENTED();
     return nullptr;
   }
+  std::unique_ptr<net::ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<net::StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const net::HostPortPair& endpoint,
+      const net::ProxyServer& proxy_server,
+      net::HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      net::NextProto negotiated_protocol,
+      net::ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const net::NetworkTrafficAnnotationTag& traffic_annotation) override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
 
   net::IPEndPoint ip_;
   // Simulated connect data
diff --git a/components/mirroring/service/BUILD.gn b/components/mirroring/service/BUILD.gn
index 2a907db3..881987b 100644
--- a/components/mirroring/service/BUILD.gn
+++ b/components/mirroring/service/BUILD.gn
@@ -2,14 +2,8 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
 import("//testing/test.gni")
 
-service_manifest("manifest") {
-  name = "mirroring"
-  source = "manifest.json"
-}
-
 component("mirroring_service") {
   sources = [
     "captured_audio_input.cc",
@@ -120,3 +114,17 @@
     "//testing/gtest",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/mirroring/mojom:constants",
+    "//components/mirroring/mojom:service",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/components/mirroring/service/OWNERS b/components/mirroring/service/OWNERS
index 59dfd4b3..6faeaa47 100644
--- a/components/mirroring/service/OWNERS
+++ b/components/mirroring/service/OWNERS
@@ -1,2 +1,4 @@
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/components/mirroring/service/manifest.cc b/components/mirroring/service/manifest.cc
new file mode 100644
index 0000000..eda50b24
--- /dev/null
+++ b/components/mirroring/service/manifest.cc
@@ -0,0 +1,32 @@
+// 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 "components/mirroring/service/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/mirroring/mojom/constants.mojom.h"
+#include "components/mirroring/mojom/mirroring_service.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace mirroring {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Mirroring Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("utility")
+                           .Build())
+          .ExposeCapability("mirroring",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::MirroringService>())
+          .RequireCapability("content_browser", "gpu_client")
+          .RequireCapability("ui", "gpu_client")
+
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace mirroring
diff --git a/components/mirroring/service/manifest.h b/components/mirroring/service/manifest.h
new file mode 100644
index 0000000..26022af
--- /dev/null
+++ b/components/mirroring/service/manifest.h
@@ -0,0 +1,16 @@
+// 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 COMPONENTS_MIRRORING_SERVICE_MANIFEST_H_
+#define COMPONENTS_MIRRORING_SERVICE_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace mirroring {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace mirroring
+
+#endif  // COMPONENTS_MIRRORING_SERVICE_MANIFEST_H_
diff --git a/components/mirroring/service/manifest.json b/components/mirroring/service/manifest.json
deleted file mode 100644
index 882edee..0000000
--- a/components/mirroring/service/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "mirroring",
-  "sandbox_type": "utility",
-  "display_name": "Mirroring Service",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "requires": {
-        "content_browser": [ "gpu_client" ],
-        "ui": [ "gpu_client" ]
-      },
-      "provides": {
-        "mirroring": [
-          "mirroring.mojom.MirroringService"
-        ]
-      }
-    }
-  }
-}
diff --git a/components/nacl/broker/BUILD.gn b/components/nacl/broker/BUILD.gn
index 4c342b0..55b3925 100644
--- a/components/nacl/broker/BUILD.gn
+++ b/components/nacl/broker/BUILD.gn
@@ -4,7 +4,6 @@
 
 import("//build/config/compiler/compiler.gni")
 import("//components/nacl/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 # This file builds nacl64.exe, which is a 64-bit x86 Windows executable
 # used only in the 32-bit x86 Windows build.  The :broker code runs both
@@ -175,7 +174,15 @@
   }
 }
 
-service_manifest("nacl_broker_manifest") {
-  name = "nacl_broker"
-  source = "nacl_broker_manifest.json"
+source_set("nacl_broker_manifest") {
+  sources = [
+    "nacl_broker_manifest.cc",
+    "nacl_broker_manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/nacl/common",
+    "//services/service_manager/public/cpp",
+  ]
 }
diff --git a/components/nacl/broker/OWNERS b/components/nacl/broker/OWNERS
index 9483650e..645e46f 100644
--- a/components/nacl/broker/OWNERS
+++ b/components/nacl/broker/OWNERS
@@ -1,3 +1,4 @@
-# Mojo manifests
-per-file nacl_broker_manifest.json=set noparent
-per-file nacl_broker_manifest.json=file://ipc/SECURITY_OWNERS
+per-file nacl_broker_manifest.cc=set noparent
+per-file nacl_broker_manifest.cc=file://ipc/SECURITY_OWNERS
+per-file nacl_broker_manifest.h=set noparent
+per-file nacl_broker_manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/components/nacl/broker/nacl_broker_manifest.cc b/components/nacl/broker/nacl_broker_manifest.cc
new file mode 100644
index 0000000..203c415
--- /dev/null
+++ b/components/nacl/broker/nacl_broker_manifest.cc
@@ -0,0 +1,33 @@
+// 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 "components/nacl/broker/nacl_broker_manifest.h"
+
+#include <set>
+
+#include "base/no_destructor.h"
+#include "components/nacl/common/nacl_constants.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+const service_manager::Manifest& GetNaClBrokerManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(nacl::kNaClBrokerServiceName)
+          .WithDisplayName("NaCl broker")
+          .WithOptions(service_manager::ManifestOptionsBuilder().Build())
+          // NOTE: The interfaces below are not implemented in the nacl_loader
+          // service, but they are requested from all child processes by common
+          // browser-side code. We list them here to make the Service Manager
+          // happy.
+          .ExposeCapability("browser",
+                            std::set<const char*>{
+                                "IPC.mojom.ChannelBootstrap",
+                                "content.mojom.Child",
+                                "content.mojom.ChildControl",
+                                "content.mojom.ChildHistogramFetcherFactory",
+                            })
+
+          .Build()};
+  return *manifest;
+}
diff --git a/components/nacl/broker/nacl_broker_manifest.h b/components/nacl/broker/nacl_broker_manifest.h
new file mode 100644
index 0000000..faada71
--- /dev/null
+++ b/components/nacl/broker/nacl_broker_manifest.h
@@ -0,0 +1,12 @@
+// 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 COMPONENTS_NACL_BROKER_NACL_BROKER_MANIFEST_H_
+#define COMPONENTS_NACL_BROKER_NACL_BROKER_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+const service_manager::Manifest& GetNaClBrokerManifest();
+
+#endif  // COMPONENTS_NACL_BROKER_NACL_BROKER_MANIFEST_H_
diff --git a/components/nacl/broker/nacl_broker_manifest.json b/components/nacl/broker/nacl_broker_manifest.json
deleted file mode 100644
index d5273bf..0000000
--- a/components/nacl/broker/nacl_broker_manifest.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "name": "nacl_broker",
-  "display_name": "NaCl broker",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "browser": [
-          "IPC.mojom.ChannelBootstrap",
-
-          // NOTE: The interfaces below are not implemented in the nacl_loader
-          // service, but they are requested from all child processes by common
-          // browser-side code. We list them here to make the Service Manager
-          // happy.
-          "content.mojom.Child",
-          "content.mojom.ChildControl",
-          "content.mojom.ChildHistogramFetcherFactory"
-        ]
-      }
-    }
-  }
-}
diff --git a/components/nacl/loader/BUILD.gn b/components/nacl/loader/BUILD.gn
index 963c64b9..39bb50e4 100644
--- a/components/nacl/loader/BUILD.gn
+++ b/components/nacl/loader/BUILD.gn
@@ -6,7 +6,6 @@
 import("//build/config/compiler/compiler.gni")
 import("//build/config/nacl/config.gni")
 import("//components/nacl/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
 import("//testing/test.gni")
 
 assert(enable_nacl)
@@ -321,7 +320,15 @@
   }
 }
 
-service_manifest("nacl_loader_manifest") {
-  name = "nacl_loader"
-  source = "nacl_loader_manifest.json"
+source_set("nacl_loader_manifest") {
+  sources = [
+    "nacl_loader_manifest.cc",
+    "nacl_loader_manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/nacl/common",
+    "//services/service_manager/public/cpp",
+  ]
 }
diff --git a/components/nacl/loader/OWNERS b/components/nacl/loader/OWNERS
index fa9c91804..bdc3641e 100644
--- a/components/nacl/loader/OWNERS
+++ b/components/nacl/loader/OWNERS
@@ -1,3 +1,4 @@
-# Mojo manifests
-per-file nacl_loader_manifest.json=set noparent
-per-file nacl_loader_manifest.json=file://ipc/SECURITY_OWNERS
+per-file nacl_loader_manifest.cc=set noparent
+per-file nacl_loader_manifest.cc=file://ipc/SECURITY_OWNERS
+per-file nacl_loader_manifest.h=set noparent
+per-file nacl_loader_manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/components/nacl/loader/nacl_loader_manifest.cc b/components/nacl/loader/nacl_loader_manifest.cc
new file mode 100644
index 0000000..e6c5f61
--- /dev/null
+++ b/components/nacl/loader/nacl_loader_manifest.cc
@@ -0,0 +1,31 @@
+// 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 "components/nacl/loader/nacl_loader_manifest.h"
+
+#include <set>
+
+#include "base/no_destructor.h"
+#include "components/nacl/common/nacl_constants.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+const service_manager::Manifest& GetNaClLoaderManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(nacl::kNaClLoaderServiceName)
+          .WithDisplayName("NaCl loader")
+          // NOTE: The interfaces below are not implemented in the nacl_loader
+          // service, but they are requested from all child processes by common
+          // browser-side code. We list them here to make the Service Manager
+          // happy.
+          .ExposeCapability(
+              "browser",
+              std::set<const char*>{
+                  "IPC.mojom.ChannelBootstrap", "content.mojom.Child",
+                  "content.mojom.ChildControl",
+                  "content.mojom.ChildHistogramFetcherFactory",
+                  "content.mojom.ResourceUsageReporter"})
+          .Build()};
+  return *manifest;
+}
diff --git a/components/nacl/loader/nacl_loader_manifest.h b/components/nacl/loader/nacl_loader_manifest.h
new file mode 100644
index 0000000..0e4c531
--- /dev/null
+++ b/components/nacl/loader/nacl_loader_manifest.h
@@ -0,0 +1,12 @@
+// 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 COMPONENTS_NACL_LOADER_NACL_LOADER_MANIFEST_H_
+#define COMPONENTS_NACL_LOADER_NACL_LOADER_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+const service_manager::Manifest& GetNaClLoaderManifest();
+
+#endif  // COMPONENTS_NACL_LOADER_NACL_LOADER_MANIFEST_H_
diff --git a/components/nacl/loader/nacl_loader_manifest.json b/components/nacl/loader/nacl_loader_manifest.json
deleted file mode 100644
index 30e0f64..0000000
--- a/components/nacl/loader/nacl_loader_manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "name": "nacl_loader",
-  "display_name": "NaCl loader",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "browser": [
-          "IPC.mojom.ChannelBootstrap",
-          "content.mojom.Child",
-          "content.mojom.ChildControl",
-          "content.mojom.ChildHistogramFetcherFactory",
-          "content.mojom.ResourceUsageReporter"
-        ]
-      }
-    }
-  }
-}
diff --git a/components/plugins/renderer/webview_plugin.h b/components/plugins/renderer/webview_plugin.h
index 9ee3812..db94a09 100644
--- a/components/plugins/renderer/webview_plugin.h
+++ b/components/plugins/renderer/webview_plugin.h
@@ -166,6 +166,7 @@
     bool CanHandleGestureEvent() override;
     bool CanUpdateLayout() override;
     blink::WebScreenInfo GetScreenInfo() override;
+    void DidInvalidateRect(const blink::WebRect&) override;
 
     // WebWidgetClient methods:
     void SetToolTipText(const blink::WebString&,
@@ -175,7 +176,6 @@
                        blink::WebDragOperationsMask,
                        const SkBitmap&,
                        const gfx::Point&) override;
-    void DidInvalidateRect(const blink::WebRect&) override;
     void DidChangeCursor(const blink::WebCursorInfo& cursor) override;
     void ScheduleAnimation() override;
     std::unique_ptr<blink::WebURLLoaderFactory> CreateURLLoaderFactory()
diff --git a/components/services/heap_profiling/BUILD.gn b/components/services/heap_profiling/BUILD.gn
index 6c18731..a319417 100644
--- a/components/services/heap_profiling/BUILD.gn
+++ b/components/services/heap_profiling/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 
 static_library("heap_profiling") {
@@ -62,11 +61,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "heap_profiling"
-  source = "heap_profiling_manifest.json"
-}
-
 fuzzer_test("profiling_fuzzer") {
   sources = [
     "stream_fuzzer.cc",
diff --git a/components/services/heap_profiling/OWNERS b/components/services/heap_profiling/OWNERS
index 80cbc1b..987c0c88 100644
--- a/components/services/heap_profiling/OWNERS
+++ b/components/services/heap_profiling/OWNERS
@@ -1,4 +1 @@
 erikchen@chromium.org
-
-per-file heap_profiling_manifest.json=set noparent
-per-file heap_profiling_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/components/services/heap_profiling/heap_profiling_manifest.json b/components/services/heap_profiling/heap_profiling_manifest.json
deleted file mode 100644
index 38bb3c5e..0000000
--- a/components/services/heap_profiling/heap_profiling_manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "name": "heap_profiling",
-  "display_name": "Heap Profiling Service",
-  "sandbox_type": "profiling",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "profiling": [ "heap_profiling.mojom.ProfilingService" ],
-        "heap_profiler": [ "memory_instrumentation.mojom.HeapProfiler" ]
-      },
-      "requires": {
-        "*": [ "app" ],
-        "resource_coordinator": [ "heap_profiler_helper" ]
-      }
-    }
-  }
-}
diff --git a/components/services/heap_profiling/public/cpp/BUILD.gn b/components/services/heap_profiling/public/cpp/BUILD.gn
index 44606b2e..01439b40 100644
--- a/components/services/heap_profiling/public/cpp/BUILD.gn
+++ b/components/services/heap_profiling/public/cpp/BUILD.gn
@@ -50,3 +50,17 @@
     "//testing/gtest",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/services/heap_profiling/public/mojom",
+    "//services/resource_coordinator/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/components/services/heap_profiling/public/cpp/OWNERS b/components/services/heap_profiling/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/components/services/heap_profiling/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/components/services/heap_profiling/public/cpp/manifest.cc b/components/services/heap_profiling/public/cpp/manifest.cc
new file mode 100644
index 0000000..bd3e16b
--- /dev/null
+++ b/components/services/heap_profiling/public/cpp/manifest.cc
@@ -0,0 +1,39 @@
+// 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 "components/services/heap_profiling/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/heap_profiling/public/mojom/constants.mojom.h"
+#include "components/services/heap_profiling/public/mojom/heap_profiling_service.mojom.h"
+#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
+#include "services/resource_coordinator/public/mojom/service_constants.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace heap_profiling {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Heap Profiling Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("profiling")
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability("profiling",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::ProfilingService>())
+          .ExposeCapability("heap_profiler",
+                            service_manager::Manifest::InterfaceList<
+                                memory_instrumentation::mojom::HeapProfiler>())
+          .RequireCapability(resource_coordinator::mojom::kServiceName,
+                             "heap_profiler_helper")
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace heap_profiling
diff --git a/components/services/heap_profiling/public/cpp/manifest.h b/components/services/heap_profiling/public/cpp/manifest.h
new file mode 100644
index 0000000..96f7f0c
--- /dev/null
+++ b/components/services/heap_profiling/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace heap_profiling {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace heap_profiling
+
+#endif  // COMPONENTS_SERVICES_HEAP_PROFILING_PUBLIC_CPP_MANIFEST_H_
diff --git a/components/services/patch/BUILD.gn b/components/services/patch/BUILD.gn
index 2a0a603..eb94d27 100644
--- a/components/services/patch/BUILD.gn
+++ b/components/services/patch/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 source_set("lib") {
   sources = [
     "file_patcher_impl.cc",
@@ -24,8 +22,3 @@
     "//services/service_manager/public/cpp",
   ]
 }
-
-service_manifest("manifest") {
-  name = "patch_service"
-  source = "manifest.json"
-}
diff --git a/components/services/patch/OWNERS b/components/services/patch/OWNERS
index f232b6d..ec81839 100644
--- a/components/services/patch/OWNERS
+++ b/components/services/patch/OWNERS
@@ -1,5 +1,2 @@
 sorin@chromium.org
 waffles@chromium.org
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/components/services/patch/manifest.json b/components/services/patch/manifest.json
deleted file mode 100644
index 75cb068a..0000000
--- a/components/services/patch/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "name": "patch_service",
-  "display_name": "Patch Service",
-  "sandbox_type": "utility",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "patch_file": [ "patch.mojom.FilePatcher" ]
-       }
-     }
-  }
-}
diff --git a/components/services/patch/public/cpp/BUILD.gn b/components/services/patch/public/cpp/BUILD.gn
index d532218..8f9c197 100644
--- a/components/services/patch/public/cpp/BUILD.gn
+++ b/components/services/patch/public/cpp/BUILD.gn
@@ -15,3 +15,16 @@
     "//services/service_manager/public/cpp",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/services/patch/public/interfaces",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/components/services/patch/public/cpp/OWNERS b/components/services/patch/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/components/services/patch/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/components/services/patch/public/cpp/manifest.cc b/components/services/patch/public/cpp/manifest.cc
new file mode 100644
index 0000000..087aa25
--- /dev/null
+++ b/components/services/patch/public/cpp/manifest.cc
@@ -0,0 +1,33 @@
+// 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 "components/services/patch/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/patch/public/interfaces/constants.mojom.h"
+#include "components/services/patch/public/interfaces/file_patcher.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace patch {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Patch Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("utility")
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability(
+              "patch_file",
+              service_manager::Manifest::InterfaceList<mojom::FilePatcher>())
+
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace patch
diff --git a/components/services/patch/public/cpp/manifest.h b/components/services/patch/public/cpp/manifest.h
new file mode 100644
index 0000000..d476dc2
--- /dev/null
+++ b/components/services/patch/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 COMPONENTS_SERVICES_PATCH_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_PATCH_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace patch {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace patch
+
+#endif  // COMPONENTS_SERVICES_PATCH_PUBLIC_CPP_MANIFEST_H_
diff --git a/components/services/pdf_compositor/BUILD.gn b/components/services/pdf_compositor/BUILD.gn
index 6b42b00..c21b77a 100644
--- a/components/services/pdf_compositor/BUILD.gn
+++ b/components/services/pdf_compositor/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//printing/buildflags/buildflags.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 static_library("pdf_compositor") {
   sources = [
@@ -33,11 +32,6 @@
   ]
 }
 
-service_manifest("pdf_compositor_manifest") {
-  name = "pdf_compositor"
-  source = "pdf_compositor_manifest.json"
-}
-
 if (enable_basic_printing) {
   source_set("unit_tests") {
     testonly = true
diff --git a/components/services/pdf_compositor/OWNERS b/components/services/pdf_compositor/OWNERS
index 5f7d2e5..9b08c66 100644
--- a/components/services/pdf_compositor/OWNERS
+++ b/components/services/pdf_compositor/OWNERS
@@ -1,4 +1 @@
 file://printing/OWNERS
-
-per-file pdf_compositor_manifest.json=set noparent
-per-file pdf_compositor_manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/components/services/pdf_compositor/pdf_compositor_manifest.json b/components/services/pdf_compositor/pdf_compositor_manifest.json
deleted file mode 100644
index ffe276b..0000000
--- a/components/services/pdf_compositor/pdf_compositor_manifest.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-  "name": "pdf_compositor",
-  "display_name": "PDF Compositor Service",
-  "sandbox_type": "pdf_compositor",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "compositor": [ "printing.mojom.PdfCompositor" ]
-       },
-       "requires": {
-         "*": [ "app" ],
-         "content_browser": [ "sandbox_support" ],
-         "ui": [ "discardable_memory" ]
-       }
-     }
-  }
-}
diff --git a/components/services/pdf_compositor/public/cpp/BUILD.gn b/components/services/pdf_compositor/public/cpp/BUILD.gn
index 1e558aa6..426a934 100644
--- a/components/services/pdf_compositor/public/cpp/BUILD.gn
+++ b/components/services/pdf_compositor/public/cpp/BUILD.gn
@@ -21,3 +21,16 @@
     "//services/service_manager/public/cpp",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/services/pdf_compositor/public/interfaces",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/components/services/pdf_compositor/public/cpp/OWNERS b/components/services/pdf_compositor/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/components/services/pdf_compositor/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/components/services/pdf_compositor/public/cpp/manifest.cc b/components/services/pdf_compositor/public/cpp/manifest.cc
new file mode 100644
index 0000000..87c2108
--- /dev/null
+++ b/components/services/pdf_compositor/public/cpp/manifest.cc
@@ -0,0 +1,34 @@
+// 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 "components/services/pdf_compositor/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace printing {
+
+const service_manager::Manifest& GetPdfCompositorManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("PDF Compositor Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("pdf_compositor")
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability(
+              "compositor",
+              service_manager::Manifest::InterfaceList<mojom::PdfCompositor>())
+          .RequireCapability("content_browser", "app")
+          .RequireCapability("content_browser", "sandbox_support")
+          .RequireCapability("ui", "discardable_memory")
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace printing
diff --git a/components/services/pdf_compositor/public/cpp/manifest.h b/components/services/pdf_compositor/public/cpp/manifest.h
new file mode 100644
index 0000000..52b57fc
--- /dev/null
+++ b/components/services/pdf_compositor/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 COMPONENTS_SERVICES_PDF_COMPOSITOR_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_PDF_COMPOSITOR_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace printing {
+
+const service_manager::Manifest& GetPdfCompositorManifest();
+
+}  // namespace printing
+
+#endif  // COMPONENTS_SERVICES_PDF_COMPOSITOR_PUBLIC_CPP_MANIFEST_H_
diff --git a/components/services/unzip/BUILD.gn b/components/services/unzip/BUILD.gn
index 020a9498..28ce034 100644
--- a/components/services/unzip/BUILD.gn
+++ b/components/services/unzip/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 source_set("lib") {
   sources = [
     "unzip_service.cc",
@@ -55,8 +53,3 @@
     "//testing/gtest",
   ]
 }
-
-service_manifest("manifest") {
-  name = "unzip_service"
-  source = "manifest.json"
-}
diff --git a/components/services/unzip/OWNERS b/components/services/unzip/OWNERS
index bd74fe69..ec81839 100644
--- a/components/services/unzip/OWNERS
+++ b/components/services/unzip/OWNERS
@@ -1,4 +1,2 @@
 sorin@chromium.org
 waffles@chromium.org
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/components/services/unzip/manifest.json b/components/services/unzip/manifest.json
deleted file mode 100644
index ab70406..0000000
--- a/components/services/unzip/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "name": "unzip_service",
-  "display_name": "Unzip Service",
-  "sandbox_type": "utility",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "unzip_file": [ "unzip.mojom.Unzipper" ]
-       }
-     }
-  }
-}
diff --git a/components/services/unzip/public/cpp/BUILD.gn b/components/services/unzip/public/cpp/BUILD.gn
index 78470fe..8deacf7 100644
--- a/components/services/unzip/public/cpp/BUILD.gn
+++ b/components/services/unzip/public/cpp/BUILD.gn
@@ -31,3 +31,16 @@
     "//services/service_manager/public/cpp/test:test_support",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/services/unzip/public/interfaces",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/components/services/unzip/public/cpp/OWNERS b/components/services/unzip/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/components/services/unzip/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/components/services/unzip/public/cpp/manifest.cc b/components/services/unzip/public/cpp/manifest.cc
new file mode 100644
index 0000000..a6ec2adb
--- /dev/null
+++ b/components/services/unzip/public/cpp/manifest.cc
@@ -0,0 +1,32 @@
+// 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 "components/services/unzip/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/unzip/public/interfaces/constants.mojom.h"
+#include "components/services/unzip/public/interfaces/unzipper.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace unzip {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Unzip Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("utility")
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability(
+              "unzip_file",
+              service_manager::Manifest::InterfaceList<mojom::Unzipper>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace unzip
diff --git a/components/services/unzip/public/cpp/manifest.h b/components/services/unzip/public/cpp/manifest.h
new file mode 100644
index 0000000..b17b2a1
--- /dev/null
+++ b/components/services/unzip/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 COMPONENTS_SERVICES_UNZIP_PUBLIC_CPP_MANIFEST_H_
+#define COMPONENTS_SERVICES_UNZIP_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace unzip {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace unzip
+
+#endif  // COMPONENTS_SERVICES_UNZIP_PUBLIC_CPP_MANIFEST_H_
diff --git a/components/ui_devtools/BUILD.gn b/components/ui_devtools/BUILD.gn
index 5fde53c..0036fafa 100644
--- a/components/ui_devtools/BUILD.gn
+++ b/components/ui_devtools/BUILD.gn
@@ -6,6 +6,8 @@
 import("$_inspector_protocol/inspector_protocol.gni")
 
 _protocol_generated = [
+  "base_string_adapter.cc",
+  "base_string_adapter.h",
   "CSS.cpp",
   "CSS.h",
   "DOM.cpp",
@@ -71,8 +73,6 @@
     "overlay_agent.h",
     "root_element.cc",
     "root_element.h",
-    "string_util.cc",
-    "string_util.h",
     "switches.cc",
     "switches.h",
     "ui_element.cc",
diff --git a/components/ui_devtools/devtools_server.cc b/components/ui_devtools/devtools_server.cc
index a1625b72..a4a1c40 100644
--- a/components/ui_devtools/devtools_server.cc
+++ b/components/ui_devtools/devtools_server.cc
@@ -168,7 +168,7 @@
 }
 
 void UiDevToolsServer::SendOverWebSocket(int connection_id,
-                                         const String& message) {
+                                         const protocol::String& message) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(devtools_server_sequence_);
   server_->SendOverWebSocket(connection_id, message, tag_);
 }
diff --git a/components/ui_devtools/devtools_server.h b/components/ui_devtools/devtools_server.h
index f4395f75..12877d1 100644
--- a/components/ui_devtools/devtools_server.h
+++ b/components/ui_devtools/devtools_server.h
@@ -16,7 +16,6 @@
 #include "components/ui_devtools/Protocol.h"
 #include "components/ui_devtools/devtools_client.h"
 #include "components/ui_devtools/devtools_export.h"
-#include "components/ui_devtools/string_util.h"
 #include "services/network/public/cpp/server/http_server.h"
 
 namespace ui_devtools {
@@ -63,7 +62,7 @@
                                int default_port);
 
   void AttachClient(std::unique_ptr<UiDevToolsClient> client);
-  void SendOverWebSocket(int connection_id, const String& message);
+  void SendOverWebSocket(int connection_id, const protocol::String& message);
 
   int port() const { return port_; }
 
diff --git a/components/ui_devtools/inspector_protocol_config.json b/components/ui_devtools/inspector_protocol_config.json
index 76292154..41062e79 100644
--- a/components/ui_devtools/inspector_protocol_config.json
+++ b/components/ui_devtools/inspector_protocol_config.json
@@ -10,7 +10,7 @@
     "lib": {
         "package": "components/ui_devtools",
         "output": "",
-        "string_header": "components/ui_devtools/string_util.h",
+        "string_header": "components/ui_devtools/base_string_adapter.h",
         "export_macro": "UI_DEVTOOLS_EXPORT",
         "export_header": "components/ui_devtools/devtools_export.h"
     }
diff --git a/components/ui_devtools/overlay_agent.cc b/components/ui_devtools/overlay_agent.cc
index 5804dc007..5cd89fbe 100644
--- a/components/ui_devtools/overlay_agent.cc
+++ b/components/ui_devtools/overlay_agent.cc
@@ -13,7 +13,7 @@
 OverlayAgent::~OverlayAgent() {}
 
 protocol::Response OverlayAgent::setInspectMode(
-    const String& in_mode,
+    const protocol::String& in_mode,
     protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
   NOTREACHED();
   return protocol::Response::OK();
diff --git a/components/ui_devtools/overlay_agent.h b/components/ui_devtools/overlay_agent.h
index 2bee58a..32578efc 100644
--- a/components/ui_devtools/overlay_agent.h
+++ b/components/ui_devtools/overlay_agent.h
@@ -18,7 +18,7 @@
 
   // Overlay::Backend:
   protocol::Response setInspectMode(
-      const String& in_mode,
+      const protocol::String& in_mode,
       protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig)
       override;
   protocol::Response highlightNode(
diff --git a/components/ui_devtools/string_util.cc b/components/ui_devtools/string_util.cc
deleted file mode 100644
index fde02a7..0000000
--- a/components/ui_devtools/string_util.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/ui_devtools/string_util.h"
-
-#include "base/strings/string_util.h"
-#include "base/strings/utf_string_conversions.h"
-#include "components/ui_devtools/Protocol.h"
-
-namespace ui_devtools {
-namespace protocol {
-
-// static
-std::unique_ptr<Value> StringUtil::parseJSON(const String& string) {
-  DCHECK(base::IsStringUTF8(string));
-  // TODO(mhashmi): 16-bit strings need to be handled
-  return parseJSONCharacters(reinterpret_cast<const uint8_t*>(&string[0]),
-                             string.length());
-};
-
-// static
-void StringUtil::builderAppendQuotedString(StringBuilder& builder,
-                                           const String& str) {
-  builder.append('"');
-  base::string16 str16 = base::UTF8ToUTF16(str);
-  escapeWideStringForJSON(reinterpret_cast<const uint16_t*>(&str16[0]),
-                          str16.length(), &builder);
-  builder.append('"');
-}
-
-}  // namespace protocol
-}  // namespace ui_devtools
diff --git a/components/ui_devtools/string_util.h b/components/ui_devtools/string_util.h
deleted file mode 100644
index 1a79c0a..0000000
--- a/components/ui_devtools/string_util.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_UI_DEVTOOLS_STRING_UTIL_H_
-#define COMPONENTS_UI_DEVTOOLS_STRING_UTIL_H_
-
-#include <memory>
-
-#include "base/json/json_reader.h"
-#include "base/strings/string_number_conversions.h"
-
-namespace ui_devtools {
-
-using String = std::string;
-
-namespace protocol {
-
-class Value;
-
-class CustomStringBuilder {
-  String s_;
-
- public:
-  CustomStringBuilder() {}
-  CustomStringBuilder(String& s) : s_(s) {}
-  void reserveCapacity(std::size_t size) { s_.reserve(size); }
-  void append(const String& s) { s_ += s; }
-  void append(char c) { s_ += c; }
-  void append(const char* data, size_t length) { s_.append(data, length); }
-  String toString() { return s_; }
-};
-
-using StringBuilder = CustomStringBuilder;
-
-class StringUtil {
- public:
-  static String substring(const String& s, unsigned pos, unsigned len) {
-    return s.substr(pos, len);
-  }
-  static String fromInteger(int number) { return base::NumberToString(number); }
-  static String fromDouble(double number) {
-    return base::NumberToString(number);
-  }
-  static double toDouble(const char* s, size_t len, bool* ok) {
-    double v = 0.0;
-    *ok = base::StringToDouble(std::string(s, len), &v);
-    return *ok ? v : 0.0;
-  }
-  static void builderAppend(StringBuilder& builder, const String& s) {
-    builder.append(s);
-  }
-  static void builderAppend(StringBuilder& builder, char c) {
-    builder.append(c);
-  }
-  static void builderAppend(StringBuilder& builder, const char* s, size_t len) {
-    builder.append(s, len);
-  }
-  static void builderAppendQuotedString(StringBuilder& builder,
-                                        const String& str);
-  static void builderReserve(StringBuilder& builder, unsigned capacity) {
-    builder.reserveCapacity(capacity);
-  }
-  static String builderToString(StringBuilder& builder) {
-    return builder.toString();
-  }
-  static size_t find(const String& s, const char* needle) {
-    return s.find(needle);
-  }
-  static size_t find(const String& s, const String& needle) {
-    return s.find(needle);
-  }
-  static const size_t kNotFound = static_cast<size_t>(-1);
-  static std::unique_ptr<Value> parseJSON(const String& string);
-};
-
-// A read-only sequence of uninterpreted bytes with reference-counted storage.
-// Though the templates for generating the protocol bindings reference
-// this type, thus far it's not used in the Chrome layer, so we provide no
-// implementation here and rely on the linker optimizing it away. If this
-// changes, look to content/browser/devtools/protocol_string{.h,.cc} for
-// inspiration.
-class Binary {
- public:
-  const uint8_t* data() const;
-  size_t size() const;
-  String toBase64() const;
-  static Binary fromBase64(const String& base64, bool* success);
-};
-}  // namespace protocol
-}  // namespace ui_devtools
-
-#endif  // COMPONENTS_UI_DEVTOOLS_STRING_UTIL_H_
diff --git a/components/ui_devtools/views/overlay_agent_aura.cc b/components/ui_devtools/views/overlay_agent_aura.cc
index bd0614a3..d7c5e6a 100644
--- a/components/ui_devtools/views/overlay_agent_aura.cc
+++ b/components/ui_devtools/views/overlay_agent_aura.cc
@@ -396,7 +396,7 @@
 }
 
 protocol::Response OverlayAgentAura::setInspectMode(
-    const String& in_mode,
+    const protocol::String& in_mode,
     protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
   pinned_id_ = 0;
   if (in_mode.compare("searchForNode") == 0) {
diff --git a/components/ui_devtools/views/overlay_agent_aura.h b/components/ui_devtools/views/overlay_agent_aura.h
index 9659ca8..fc0b6ae 100644
--- a/components/ui_devtools/views/overlay_agent_aura.h
+++ b/components/ui_devtools/views/overlay_agent_aura.h
@@ -53,7 +53,7 @@
 
   // Overlay::Backend:
   protocol::Response setInspectMode(
-      const String& in_mode,
+      const protocol::String& in_mode,
       protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig)
       override;
   protocol::Response highlightNode(
diff --git a/components/ui_devtools/viz/overlay_agent_viz.cc b/components/ui_devtools/viz/overlay_agent_viz.cc
index 7501924..85e7d62 100644
--- a/components/ui_devtools/viz/overlay_agent_viz.cc
+++ b/components/ui_devtools/viz/overlay_agent_viz.cc
@@ -12,7 +12,7 @@
 OverlayAgentViz::~OverlayAgentViz() {}
 
 protocol::Response OverlayAgentViz::setInspectMode(
-    const String& in_mode,
+    const protocol::String& in_mode,
     protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig) {
   return protocol::Response::OK();
 }
diff --git a/components/ui_devtools/viz/overlay_agent_viz.h b/components/ui_devtools/viz/overlay_agent_viz.h
index c71652c6..5310716 100644
--- a/components/ui_devtools/viz/overlay_agent_viz.h
+++ b/components/ui_devtools/viz/overlay_agent_viz.h
@@ -18,7 +18,7 @@
 
   // Overlay::Backend:
   protocol::Response setInspectMode(
-      const String& in_mode,
+      const protocol::String& in_mode,
       protocol::Maybe<protocol::Overlay::HighlightConfig> in_highlightConfig)
       override;
   protocol::Response highlightNode(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index eaeb87e..9bcbb0a 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -232,6 +232,8 @@
   ]
 
   sources = [
+    "$target_gen_dir/devtools/protocol/base_string_adapter.cc",
+    "$target_gen_dir/devtools/protocol/base_string_adapter.h",
     "$target_gen_dir/devtools/protocol/browser.cc",
     "$target_gen_dir/devtools/protocol/browser.h",
     "$target_gen_dir/devtools/protocol/dom.cc",
@@ -720,8 +722,6 @@
     "devtools/protocol/tethering_handler.h",
     "devtools/protocol/tracing_handler.cc",
     "devtools/protocol/tracing_handler.h",
-    "devtools/protocol_string.cc",
-    "devtools/protocol_string.h",
     "devtools/render_frame_devtools_agent_host.cc",
     "devtools/render_frame_devtools_agent_host.h",
     "devtools/service_worker_devtools_agent_host.cc",
@@ -1845,6 +1845,8 @@
     "web_package/signed_exchange_prologue.h",
     "web_package/signed_exchange_request_handler.cc",
     "web_package/signed_exchange_request_handler.h",
+    "web_package/signed_exchange_request_matcher.cc",
+    "web_package/signed_exchange_request_matcher.h",
     "web_package/signed_exchange_signature_header_field.cc",
     "web_package/signed_exchange_signature_header_field.h",
     "web_package/signed_exchange_signature_verifier.cc",
@@ -2065,6 +2067,7 @@
       "imm32.lib",
       "oleacc.lib",
       "portabledeviceguids.lib",
+      "uiautomationcore.lib",
       "wtsapi32.lib",
     ]
   }
diff --git a/content/browser/accessibility/browser_accessibility_win_unittest.cc b/content/browser/accessibility/browser_accessibility_win_unittest.cc
index 7df056d4..df5931f 100644
--- a/content/browser/accessibility/browser_accessibility_win_unittest.cc
+++ b/content/browser/accessibility/browser_accessibility_win_unittest.cc
@@ -12,8 +12,8 @@
 #include <utility>
 
 #include "base/macros.h"
-#include "base/test/scoped_task_environment.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_environment.h"
 #include "base/win/scoped_bstr.h"
 #include "base/win/scoped_variant.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
@@ -23,6 +23,7 @@
 #include "content/common/accessibility_messages.h"
 #include "content/public/test/test_browser_thread_bundle.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/accessibility/accessibility_switches.h"
 #include "ui/accessibility/platform/ax_platform_node_win.h"
 #include "ui/base/win/atl_module.h"
 
@@ -2486,4 +2487,13 @@
   EXPECT_EQ(2, n_relations);
 }
 
+TEST_F(BrowserAccessibilityWinTest, TestUIASwitch) {
+  EXPECT_FALSE(::switches::IsExperimentalAccessibilityPlatformUIAEnabled());
+
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      ::switches::kEnableExperimentalUIAutomation);
+
+  EXPECT_TRUE(::switches::IsExperimentalAccessibilityPlatformUIAEnabled());
+}
+
 }  // namespace content
diff --git a/content/browser/browser_child_process_host_impl.cc b/content/browser/browser_child_process_host_impl.cc
index 1ba09d4..23a010b 100644
--- a/content/browser/browser_child_process_host_impl.cc
+++ b/content/browser/browser_child_process_host_impl.cc
@@ -313,7 +313,7 @@
       *base::CommandLine::ForCurrentProcess();
   static const char* const kForwardSwitches[] = {
       service_manager::switches::kDisableInProcessStackTraces,
-      switches::kDisableBackgroundTasks,
+      switches::kDisableBestEffortTasks,
       switches::kDisableLogging,
       switches::kEnableLogging,
       switches::kEnablePerfetto,
diff --git a/content/browser/devtools/BUILD.gn b/content/browser/devtools/BUILD.gn
index bb850cc..ec74261a 100644
--- a/content/browser/devtools/BUILD.gn
+++ b/content/browser/devtools/BUILD.gn
@@ -2,9 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//tools/grit/grit_rule.gni")
 import("//third_party/brotli/brotli.gni")
 import("//third_party/inspector_protocol/inspector_protocol.gni")
+import("//tools/grit/grit_rule.gni")
 
 group("resources") {
   if (!is_android) {
@@ -75,6 +75,8 @@
 
   # These are relative to $target_gen_dir.
   outputs = [
+    "protocol/base_string_adapter.cc",
+    "protocol/base_string_adapter.h",
     "protocol/browser.cc",
     "protocol/browser.h",
     "protocol/dom.cc",
diff --git a/content/browser/devtools/devtools_session.cc b/content/browser/devtools/devtools_session.cc
index 0046e22..b7165ca 100644
--- a/content/browser/devtools/devtools_session.cc
+++ b/content/browser/devtools/devtools_session.cc
@@ -37,16 +37,6 @@
 
 }  // namespace
 
-// static
-bool DevToolsSession::IsRuntimeResumeCommand(base::Value* value) {
-  if (value && value->is_dict()) {
-    base::Value* method = value->FindKey(kMethod);
-    return method && method->is_string() &&
-           method->GetString() == kResumeMethod;
-  }
-  return false;
-}
-
 DevToolsSession::DevToolsSession(DevToolsAgentHostClient* client)
     : binding_(this),
       client_(client),
@@ -144,28 +134,27 @@
 }
 
 bool DevToolsSession::DispatchProtocolMessage(const std::string& message) {
-  std::unique_ptr<base::DictionaryValue> parsed_message =
-      base::DictionaryValue::From(base::JSONReader::Read(message));
+  std::unique_ptr<protocol::DictionaryValue> value =
+      protocol::DictionaryValue::cast(protocol::StringUtil::parseJSON(message));
 
   std::string session_id;
-  if (!parsed_message || !parsed_message->GetString(kSessionId, &session_id))
-    return DispatchProtocolMessageInternal(message, std::move(parsed_message));
+  if (!value || !value->getString(kSessionId, &session_id))
+    return DispatchProtocolMessageInternal(message, std::move(value));
 
   auto it = child_sessions_.find(session_id);
   if (it == child_sessions_.end())
     return false;
   DevToolsSession* session = it->second;
-  return session->DispatchProtocolMessageInternal(message,
-                                                  std::move(parsed_message));
+  return session->DispatchProtocolMessageInternal(message, std::move(value));
 }
 
 bool DevToolsSession::DispatchProtocolMessageInternal(
     const std::string& message,
-    std::unique_ptr<base::DictionaryValue> parsed_message) {
-  if (!runtime_resume_.is_null() &&
-      IsRuntimeResumeCommand(parsed_message.get())) {
+    std::unique_ptr<protocol::DictionaryValue> value) {
+  std::string method;
+  bool has_method = value && value->getString(kMethod, &method);
+  if (!runtime_resume_.is_null() && has_method && method == kResumeMethod)
     std::move(runtime_resume_).Run();
-  }
 
   if (proxy_delegate_) {
     proxy_delegate_->SendMessageToBackend(this, message);
@@ -174,29 +163,26 @@
 
   DevToolsManagerDelegate* delegate =
       DevToolsManager::GetInstance()->delegate();
-  if (delegate && parsed_message) {
-    delegate->HandleCommand(agent_host_, client_, std::move(parsed_message),
-                            message,
-                            base::BindOnce(&DevToolsSession::HandleCommand,
-                                           weak_factory_.GetWeakPtr()));
+  if (delegate && has_method) {
+    delegate->HandleCommand(
+        agent_host_, client_, method, message,
+        base::BindOnce(&DevToolsSession::HandleCommand,
+                       weak_factory_.GetWeakPtr(), std::move(value)));
   } else {
-    HandleCommand(std::move(parsed_message), message);
+    HandleCommand(std::move(value), message);
   }
   return true;
 }
 
 void DevToolsSession::HandleCommand(
-    std::unique_ptr<base::DictionaryValue> parsed_message,
+    std::unique_ptr<protocol::DictionaryValue> value,
     const std::string& message) {
-  std::unique_ptr<protocol::Value> protocol_command =
-      protocol::toProtocolValue(parsed_message.get(), 1000);
   int call_id;
   std::string method;
-  if (!dispatcher_->parseCommand(protocol_command.get(), &call_id, &method))
+  if (!dispatcher_->parseCommand(value.get(), &call_id, &method))
     return;
   if (browser_only_ || dispatcher_->canDispatch(method)) {
-    dispatcher_->dispatch(call_id, method, std::move(protocol_command),
-                          message);
+    dispatcher_->dispatch(call_id, method, std::move(value), message);
   } else {
     fallThrough(call_id, method, message);
   }
diff --git a/content/browser/devtools/devtools_session.h b/content/browser/devtools/devtools_session.h
index d17677d..71fdd834 100644
--- a/content/browser/devtools/devtools_session.h
+++ b/content/browser/devtools/devtools_session.h
@@ -56,7 +56,6 @@
                      std::unique_ptr<protocol::DevToolsDomainHandler>>;
   HandlersMap& handlers() { return handlers_; }
 
-  static bool IsRuntimeResumeCommand(base::Value* value);
   DevToolsSession* AttachChildSession(const std::string& session_id,
                                       DevToolsAgentHostImpl* agent_host,
                                       DevToolsAgentHostClient* client);
@@ -69,11 +68,11 @@
   void DispatchProtocolMessageToAgent(int call_id,
                                       const std::string& method,
                                       const std::string& message);
-  void HandleCommand(std::unique_ptr<base::DictionaryValue> parsed_message,
+  void HandleCommand(std::unique_ptr<protocol::DictionaryValue> value,
                      const std::string& message);
   bool DispatchProtocolMessageInternal(
       const std::string& message,
-      std::unique_ptr<base::DictionaryValue> parsed_message);
+      std::unique_ptr<protocol::DictionaryValue> value);
 
   // protocol::FrontendChannel implementation.
   void sendProtocolResponse(
diff --git a/content/browser/devtools/protocol/browser_handler.cc b/content/browser/devtools/protocol/browser_handler.cc
index d2be2a4..17af579 100644
--- a/content/browser/devtools/protocol/browser_handler.cc
+++ b/content/browser/devtools/protocol/browser_handler.cc
@@ -14,6 +14,7 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "content/browser/devtools/devtools_manager.h"
+#include "content/browser/gpu/gpu_process_host.h"
 #include "content/browser/permissions/permission_controller_impl.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/content_browser_client.h"
@@ -278,5 +279,15 @@
   return Response::OK();
 }
 
+Response BrowserHandler::CrashGpuProcess() {
+  GpuProcessHost::CallOnIO(GpuProcessHost::GPU_PROCESS_KIND_SANDBOXED,
+                           false /* force_create */,
+                           base::BindOnce([](GpuProcessHost* host) {
+                             if (host)
+                               host->gpu_service()->Crash();
+                           }));
+  return Response::OK();
+}
+
 }  // namespace protocol
 }  // namespace content
diff --git a/content/browser/devtools/protocol/browser_handler.h b/content/browser/devtools/protocol/browser_handler.h
index 3b8515a..eeaf4e6dc 100644
--- a/content/browser/devtools/protocol/browser_handler.h
+++ b/content/browser/devtools/protocol/browser_handler.h
@@ -54,6 +54,7 @@
   Response ResetPermissions(Maybe<std::string> browser_context_id) override;
 
   Response Crash() override;
+  Response CrashGpuProcess() override;
 
  private:
   Response FindBrowserContext(const Maybe<std::string>& browser_context_id,
diff --git a/content/browser/devtools/protocol/target_handler.cc b/content/browser/devtools/protocol/target_handler.cc
index 708fd40..ea20d27 100644
--- a/content/browser/devtools/protocol/target_handler.cc
+++ b/content/browser/devtools/protocol/target_handler.cc
@@ -28,7 +28,9 @@
 
 namespace {
 
-const char kNotAllowedError[] = "Not allowed.";
+static const char kNotAllowedError[] = "Not allowed.";
+static const char kMethod[] = "method";
+static const char kResumeMethod[] = "Runtime.runIfWaitingForDebugger";
 
 static const char kInitializerScript[] = R"(
   (function() {
@@ -313,8 +315,11 @@
 
   void SendMessageToAgentHost(const std::string& message) {
     if (throttle_) {
-      std::unique_ptr<base::Value> value = base::JSONReader::Read(message);
-      if (DevToolsSession::IsRuntimeResumeCommand(value.get()))
+      std::unique_ptr<protocol::DictionaryValue> value =
+          protocol::DictionaryValue::cast(
+              protocol::StringUtil::parseJSON(message));
+      std::string method;
+      if (value->getString(kMethod, &method) && method == kResumeMethod)
         ResumeIfThrottled();
     }
 
diff --git a/content/browser/devtools/protocol_config.json b/content/browser/devtools/protocol_config.json
index 2bec648..c8ad5d4 100644
--- a/content/browser/devtools/protocol_config.json
+++ b/content/browser/devtools/protocol_config.json
@@ -11,7 +11,7 @@
         "options": [
             {
                 "domain": "Browser",
-                "include": ["getVersion", "getHistograms", "getHistogram", "getBrowserCommandLine", "grantPermissions", "resetPermissions", "crash"]
+                "include": ["getVersion", "getHistograms", "getHistogram", "getBrowserCommandLine", "grantPermissions", "resetPermissions", "crash", "crashGpuProcess"]
             },
             {
                 "domain": "DOM",
@@ -98,7 +98,7 @@
     "lib": {
         "package": "content/browser/devtools/protocol",
         "output": "protocol",
-        "string_header": "content/browser/devtools/protocol_string.h",
+        "string_header": "content/browser/devtools/protocol/base_string_adapter.h",
         "export_macro": "CONTENT_EXPORT",
         "export_header": "content/common/content_export.h"
     }
diff --git a/content/browser/devtools/protocol_string.h b/content/browser/devtools/protocol_string.h
deleted file mode 100644
index 83cf975..0000000
--- a/content/browser/devtools/protocol_string.h
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CONTENT_BROWSER_DEVTOOLS_PROTOCOL_STRING_H_
-#define CONTENT_BROWSER_DEVTOOLS_PROTOCOL_STRING_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted_memory.h"
-#include "base/strings/string_number_conversions.h"
-#include "content/common/content_export.h"
-
-namespace base {
-class Value;
-}
-
-namespace content {
-namespace protocol {
-
-class Value;
-
-using String = std::string;
-
-class CONTENT_EXPORT StringBuilder {
- public:
-  StringBuilder();
-  ~StringBuilder();
-  void append(const String&);
-  void append(char);
-  void append(const char*, size_t);
-  String toString();
-  void reserveCapacity(size_t);
-
- private:
-  std::string string_;
-};
-
-class CONTENT_EXPORT StringUtil {
- public:
-  static String substring(const String& s, unsigned pos, unsigned len) {
-    return s.substr(pos, len);
-  }
-  static String fromInteger(int number) { return base::NumberToString(number); }
-  static String fromDouble(double number) {
-    String s = base::NumberToString(number);
-    if (!s.empty() && s[0] == '.')
-      s = "0" + s;
-    return s;
-  }
-  static double toDouble(const char* s, size_t len, bool* ok) {
-    double v = 0.0;
-    *ok = base::StringToDouble(std::string(s, len), &v);
-    return *ok ? v : 0.0;
-  }
-  static size_t find(const String& s, const char* needle) {
-    return s.find(needle);
-  }
-  static size_t find(const String& s, const String& needle) {
-    return s.find(needle);
-  }
-  static const size_t kNotFound = static_cast<size_t>(-1);
-  static void builderAppend(StringBuilder& builder, const String& s) {
-    builder.append(s);
-  }
-  static void builderAppend(StringBuilder& builder, char c) {
-    builder.append(c);
-  }
-  static void builderAppend(StringBuilder& builder, const char* s, size_t len) {
-    builder.append(s, len);
-  }
-  static void builderAppendQuotedString(StringBuilder& builder,
-                                        const String& str);
-  static void builderReserve(StringBuilder& builder, unsigned capacity) {
-    builder.reserveCapacity(capacity);
-  }
-  static String builderToString(StringBuilder& builder) {
-    return builder.toString();
-  }
-
-  static std::unique_ptr<protocol::Value> parseJSON(const String&);
-};
-
-// A read-only sequence of uninterpreted bytes with reference-counted storage.
-class CONTENT_EXPORT Binary {
- public:
-  Binary(const Binary&);
-  Binary();
-  ~Binary();
-
-  const uint8_t* data() const { return bytes_->front(); }
-  size_t size() const { return bytes_->size(); }
-  scoped_refptr<base::RefCountedMemory> bytes() const { return bytes_; }
-
-  String toBase64() const;
-
-  static Binary fromBase64(const String& base64, bool* success);
-  static Binary fromRefCounted(scoped_refptr<base::RefCountedMemory> memory);
-  static Binary fromVector(std::vector<uint8_t> data);
-  static Binary fromString(std::string data);
-
- private:
-  explicit Binary(scoped_refptr<base::RefCountedMemory> bytes);
-  scoped_refptr<base::RefCountedMemory> bytes_;
-};
-
-std::unique_ptr<protocol::Value> toProtocolValue(
-    const base::Value* value, int depth);
-std::unique_ptr<base::Value> toBaseValue(protocol::Value* value, int depth);
-
-}  // namespace protocol
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_DEVTOOLS_PROTOCOL_STRING_H_
diff --git a/content/browser/devtools/protocol_unittest.cc b/content/browser/devtools/protocol_unittest.cc
index e3801e3..204b53a2 100644
--- a/content/browser/devtools/protocol_unittest.cc
+++ b/content/browser/devtools/protocol_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/devtools/protocol_string.h"
+#include "content/browser/devtools/protocol/base_string_adapter.h"
 
 #include <vector>
 #include "testing/gtest/include/gtest/gtest.h"
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 37770fc..16c5873 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -5682,6 +5682,11 @@
 #if !defined(OS_ANDROID)
 void RenderFrameHostImpl::BindSerialServiceRequest(
     blink::mojom::SerialServiceRequest request) {
+  if (!IsFeatureEnabled(blink::mojom::FeaturePolicyFeature::kSerial)) {
+    mojo::ReportBadMessage("Feature policy blocks access to Serial.");
+    return;
+  }
+
   if (!serial_service_)
     serial_service_ = std::make_unique<SerialService>(this);
 
diff --git a/content/browser/renderer_host/input/autoscroll_browsertest.cc b/content/browser/renderer_host/input/autoscroll_browsertest.cc
index 25ada09..c7339bc 100644
--- a/content/browser/renderer_host/input/autoscroll_browsertest.cc
+++ b/content/browser/renderer_host/input/autoscroll_browsertest.cc
@@ -219,7 +219,9 @@
 
 // Tests that the GSU and GSE events generated from the autoscroll fling have
 // non-zero positions in widget.
-IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest, GSUGSEValidPositionInWidget) {
+// Disabled due to flakiness. See https://crbug.com/930011.
+IN_PROC_BROWSER_TEST_F(AutoscrollBrowserTest,
+                       DISABLED_GSUGSEValidPositionInWidget) {
   LoadURL(kAutoscrollDataURL);
 
   // Start autoscroll with middle click.
diff --git a/content/browser/renderer_host/legacy_render_widget_host_win.cc b/content/browser/renderer_host/legacy_render_widget_host_win.cc
index 7df8a09..775c24e4 100644
--- a/content/browser/renderer_host/legacy_render_widget_host_win.cc
+++ b/content/browser/renderer_host/legacy_render_widget_host_win.cc
@@ -17,6 +17,7 @@
 #include "content/browser/renderer_host/render_widget_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
 #include "content/public/common/content_switches.h"
+#include "ui/accessibility/accessibility_switches.h"
 #include "ui/accessibility/platform/ax_system_caret_win.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_tree_host.h"
@@ -218,9 +219,9 @@
   DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param));
 
   if (kIdScreenReaderHoneyPot == obj_id) {
-    // When an MSAA client has responded to our fake event on this id,
-    // enable basic accessibility support. (Full screen reader support is
-    // detected later when specific more advanced APIs are accessed.)
+    // When an MSAA client has responded to fake event for this id,
+    // only basic accessibility support is enabled. (Full screen reader support
+    // is detected later when specific, more advanced APIs are accessed.)
     for (ui::IAccessible2UsageObserver& observer :
          ui::GetIAccessible2UsageObserverList()) {
       observer.OnScreenReaderHoneyPotQueried();
@@ -231,7 +232,21 @@
   if (!host_)
     return static_cast<LRESULT>(0L);
 
-  if (static_cast<DWORD>(OBJID_CLIENT) == obj_id) {
+  bool is_uia_request = static_cast<DWORD>(UiaRootObjectId) == obj_id;
+  bool is_msaa_request = static_cast<DWORD>(OBJID_CLIENT) == obj_id;
+
+  if ((is_uia_request &&
+       ::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) ||
+      (is_msaa_request &&
+       !::switches::IsExperimentalAccessibilityPlatformUIAEnabled())) {
+    if (is_uia_request) {
+      // UIA, by design, insulates providers from knowing about the client(s)
+      // asking for information. When UIA interface is requested, the presence
+      // of a full-fledged accessibility technology is assumed and all support
+      // is enabled.
+      BrowserAccessibilityStateImpl::GetInstance()->EnableAccessibility();
+    }
+
     RenderWidgetHostImpl* rwhi =
         RenderWidgetHostImpl::From(host_->GetRenderWidgetHost());
     if (!rwhi)
@@ -243,10 +258,17 @@
     if (!manager || !manager->GetRoot())
       return static_cast<LRESULT>(0L);
 
-    Microsoft::WRL::ComPtr<IAccessible> root(
-        ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM());
-    return LresultFromObject(IID_IAccessible, w_param,
-                             static_cast<IAccessible*>(root.Detach()));
+    BrowserAccessibilityComWin* root =
+        ToBrowserAccessibilityWin(manager->GetRoot())->GetCOM();
+
+    if (is_uia_request) {
+      Microsoft::WRL::ComPtr<IRawElementProviderSimple> root_uia(root);
+      return UiaReturnRawElementProvider(hwnd(), w_param, l_param,
+                                         root_uia.Detach());
+    } else {
+      Microsoft::WRL::ComPtr<IAccessible> root_msaa(root);
+      return LresultFromObject(IID_IAccessible, w_param, root_msaa.Detach());
+    }
   }
 
   if (static_cast<DWORD>(OBJID_CARET) == obj_id && host_->HasFocus()) {
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 2e6afef8..9045c813 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -2933,8 +2933,8 @@
     switches::kDisable2dCanvasImageChromium,
     switches::kDisableAcceleratedJpegDecoding,
     switches::kDisableAcceleratedVideoDecode,
-    switches::kDisableBackgroundTasks,
     switches::kDisableBackgroundTimerThrottling,
+    switches::kDisableBestEffortTasks,
     switches::kDisableBreakpad,
     switches::kDisableCompositorUkmForTests,
     switches::kDisablePreferCompositingToLCDText,
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.cc b/content/browser/renderer_host/render_widget_host_input_event_router.cc
index 0ab5c78..76db4e0b 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.cc
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.cc
@@ -275,8 +275,8 @@
       it.second.target = nullptr;
   }
 
-  if (view == mouse_capture_target_.target)
-    mouse_capture_target_.target = nullptr;
+  if (view == mouse_capture_target_)
+    mouse_capture_target_ = nullptr;
 
   if (view == touchscreen_gesture_target_.target)
     touchscreen_gesture_target_.target = nullptr;
@@ -378,10 +378,10 @@
 
   // Ignore mouse_capture_target_ if there are no mouse buttons currently down
   // because this is only for the purpose of dragging.
-  if (!target && mouse_capture_target_.target &&
+  if (!target && mouse_capture_target_ &&
       (event.GetType() == blink::WebInputEvent::kMouseUp ||
        IsMouseButtonDown(event))) {
-    target = mouse_capture_target_.target;
+    target = mouse_capture_target_;
   }
 
   gfx::PointF transformed_point;
@@ -544,14 +544,14 @@
   // Also, this is strictly necessary for touch emulation.
   if (mouse_event.GetType() == blink::WebInputEvent::kMouseUp ||
       !IsMouseButtonDown(mouse_event))
-    mouse_capture_target_.target = nullptr;
+    mouse_capture_target_ = nullptr;
 
   // When touch emulation is active, mouse events have to act like touch
   // events, which requires that there be implicit capture between MouseDown
   // and MouseUp.
   if (mouse_event.GetType() == blink::WebInputEvent::kMouseDown &&
       touch_emulator_ && touch_emulator_->enabled()) {
-    mouse_capture_target_.target = target;
+    mouse_capture_target_ = target;
   }
 
   DCHECK(target_location.has_value());
@@ -1787,18 +1787,18 @@
     return;
 
   if (capture) {
-    mouse_capture_target_.target = target;
+    mouse_capture_target_ = target;
     return;
   }
 
-  if (mouse_capture_target_.target == target)
-    mouse_capture_target_.target = nullptr;
+  if (mouse_capture_target_ == target)
+    mouse_capture_target_ = nullptr;
 }
 
 RenderWidgetHostImpl*
 RenderWidgetHostInputEventRouter::GetMouseCaptureWidgetForTests() const {
-  if (mouse_capture_target_.target)
-    return mouse_capture_target_.target->host();
+  if (mouse_capture_target_)
+    return mouse_capture_target_->host();
   return nullptr;
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h
index 83c695a..33a8771 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.h
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -341,7 +341,7 @@
   // Used to target wheel events for the duration of a scroll.
   RenderWidgetHostViewBase* wheel_target_ = nullptr;
   // Maintains the same target between mouse down and mouse up.
-  TargetData mouse_capture_target_;
+  RenderWidgetHostViewBase* mouse_capture_target_ = nullptr;
 
   // Tracked for the purpose of generating MouseEnter and MouseLeave events.
   RenderWidgetHostViewBase* last_mouse_move_target_;
diff --git a/content/browser/serial/serial_service.cc b/content/browser/serial/serial_service.cc
index 8a6cf13..d62e9ece 100644
--- a/content/browser/serial/serial_service.cc
+++ b/content/browser/serial/serial_service.cc
@@ -6,9 +6,12 @@
 
 #include <utility>
 
+#include "base/callback.h"
 #include "content/public/browser/content_browser_client.h"
+#include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/serial_chooser.h"
 #include "content/public/browser/serial_delegate.h"
+#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h"
 
 namespace content {
 
@@ -30,7 +33,10 @@
 }  // namespace
 
 SerialService::SerialService(RenderFrameHost* render_frame_host)
-    : render_frame_host_(render_frame_host) {}
+    : render_frame_host_(render_frame_host) {
+  DCHECK(render_frame_host_->IsFeatureEnabled(
+      blink::mojom::FeaturePolicyFeature::kSerial));
+}
 
 SerialService::~SerialService() = default;
 
diff --git a/content/browser/web_package/signed_exchange_request_matcher.cc b/content/browser/web_package/signed_exchange_request_matcher.cc
new file mode 100644
index 0000000..c34d35d9
--- /dev/null
+++ b/content/browser/web_package/signed_exchange_request_matcher.cc
@@ -0,0 +1,433 @@
+// 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 "content/browser/web_package/signed_exchange_request_matcher.h"
+
+#include <algorithm>
+#include <memory>
+#include <utility>
+
+#include "base/containers/span.h"
+#include "base/optional.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
+#include "net/base/mime_util.h"
+#include "net/http/http_util.h"
+
+namespace content {
+
+namespace {
+
+constexpr char kVariantsHeader[] = "variants-04";
+constexpr char kVariantKeyHeader[] = "variant-key-04";
+constexpr char kIdentity[] = "identity";
+
+class ContentNegotiationAlgorithm {
+ public:
+  virtual ~ContentNegotiationAlgorithm() = default;
+  // Returns items from |available_values| that satisfy the request, in
+  // preference order. Each subclass should implement the algorithm defined by
+  // content negotiation mechanism.
+  virtual std::vector<std::string> run(
+      base::span<const std::string> available_values,
+      base::Optional<std::string> request_header_value) = 0;
+
+ protected:
+  struct WeightedValue {
+    std::string value;
+    double weight;
+
+    bool operator<(const WeightedValue& other) const {
+      return weight > other.weight;  // Descending order
+    }
+  };
+
+  // Parses an Accept (Section 5.3.2 of [RFC7231]), an Accept-Encoding (Section
+  // 5.3.3 of [RFC7231]), or an Accept-Language (Section 5.3.5 of [RFC7231]).
+  // Returns items sorted by descending order of their weight, omitting items
+  // with weight of 0.
+  std::vector<WeightedValue> ParseRequestHeaderValue(
+      const base::Optional<std::string>& request_header_value) {
+    std::vector<WeightedValue> items;
+    if (!request_header_value)
+      return items;
+
+    // Value can start with '*', so it cannot be parsed by
+    // http_structured_header::ParseParameterisedList.
+    net::HttpUtil::ValuesIterator values(request_header_value->begin(),
+                                         request_header_value->end(), ',');
+    while (values.GetNext()) {
+      net::HttpUtil::NameValuePairsIterator name_value_pairs(
+          values.value_begin(), values.value_end(), ';',
+          net::HttpUtil::NameValuePairsIterator::Values::NOT_REQUIRED,
+          net::HttpUtil::NameValuePairsIterator::Quotes::STRICT_QUOTES);
+      if (!name_value_pairs.GetNext())
+        continue;
+      WeightedValue item;
+      item.value = name_value_pairs.name();
+      item.weight = 1.0;
+      while (name_value_pairs.GetNext()) {
+        if (base::LowerCaseEqualsASCII(name_value_pairs.name(), "q")) {
+          if (auto value = GetQValue(name_value_pairs.value()))
+            item.weight = *value;
+        } else {
+          // Parameters except for "q" are included in the output.
+          item.value +=
+              ';' + name_value_pairs.name() + '=' + name_value_pairs.value();
+        }
+      }
+      if (item.weight != 0.0)
+        items.push_back(std::move(item));
+    }
+    std::stable_sort(items.begin(), items.end());
+    return items;
+  }
+
+ private:
+  base::Optional<double> GetQValue(const std::string& str) {
+    // TODO(ksakamoto): Validate the syntax per Section 5.3.1 of [RFC7231],
+    // by factoring out the logic in HttpUtil::ParseAcceptEncoding().
+    double val;
+    if (!base::StringToDouble(str, &val))
+      return base::nullopt;
+    if (val < 0.0 || val > 1.0)
+      return base::nullopt;
+    return val;
+  }
+};
+
+// https://httpwg.org/http-extensions/draft-ietf-httpbis-variants.html#content-type
+class ContentTypeNegotiation final : public ContentNegotiationAlgorithm {
+  std::vector<std::string> run(
+      base::span<const std::string> available_values,
+      base::Optional<std::string> request_header_value) override {
+    // Step 1. Let preferred-available be an empty list. [spec text]
+    std::vector<std::string> preferred_available;
+
+    // Step 2. Let preferred-types be a list of the types in the request-value
+    // (or the empty list if request-value is null), ordered by their weight,
+    // highest to lowest, as per Section 5.3.2 of [RFC7231] (omitting any coding
+    // with a weight of 0). If a type lacks an explicit weight, an
+    // implementation MAY assign one.
+    std::vector<WeightedValue> preferred_types =
+        ParseRequestHeaderValue(request_header_value);
+
+    // Step 3. For each preferred-type in preferred-types: [spec text]
+    for (const WeightedValue& preferred_type : preferred_types) {
+      // 3.1. If any member of available-values matches preferred-type, using
+      // the media-range matching mechanism specified in Section 5.3.2 of
+      // [RFC7231] (which is case-insensitive), append those members of
+      // available-values to preferred-available (preserving the precedence
+      // order implied by the media ranges' specificity).
+      for (const std::string& available : available_values) {
+        if (net::MatchesMimeType(preferred_type.value, available))
+          preferred_available.push_back(available);
+      }
+    }
+
+    // Step 4. If preferred-available is empty, append the first member of
+    // available-values to preferred-available. This makes the first
+    // available-value the default when none of the client's preferences are
+    // available. [spec text]
+    if (preferred_available.empty() && !available_values.empty())
+      preferred_available.push_back(available_values[0]);
+
+    // Step 5. Return preferred-available. [spec text]
+    return preferred_available;
+  }
+};
+
+// https://httpwg.org/http-extensions/draft-ietf-httpbis-variants.html#content-encoding
+class AcceptEncodingNegotiation final : public ContentNegotiationAlgorithm {
+  std::vector<std::string> run(
+      base::span<const std::string> available_values,
+      base::Optional<std::string> request_header_value) override {
+    // Step 1. Let preferred-available be an empty list. [spec text]
+    std::vector<std::string> preferred_available;
+
+    // Step 2. Let preferred-codings be a list of the codings in the
+    // request-value (or the empty list if request-value is null), ordered by
+    // their weight, highest to lowest, as per Section 5.3.1 of [RFC7231]
+    // (omitting any coding with a weight of 0). If a coding lacks an explicit
+    // weight, an implementation MAY assign one. [spec text]
+    std::vector<WeightedValue> preferred_codings =
+        ParseRequestHeaderValue(request_header_value);
+
+    // Step 3. If "identity" is not a member of preferred-codings, append
+    // "identity". [spec text]
+    if (!std::any_of(
+            preferred_codings.begin(), preferred_codings.end(),
+            [](const WeightedValue& p) { return p.value == kIdentity; })) {
+      preferred_codings.push_back({kIdentity, 0.0});
+    }
+
+    // Step 4. Append "identity" to available-values. [spec text]
+    // Instead, we explicitly check "identity" in Step 5.1 below.
+
+    // Step 5. For each preferred-coding in preferred-codings: [spec text]
+    for (const WeightedValue& preferred_coding : preferred_codings) {
+      // Step 5.1. If there is a case-insensitive, character-for-character match
+      // for preferred-coding in available-values, append that member of
+      // available-values to preferred-available. [spec text]
+      if (preferred_coding.value == kIdentity) {
+        preferred_available.push_back(kIdentity);
+        continue;
+      }
+      for (const std::string& available : available_values) {
+        if (base::EqualsCaseInsensitiveASCII(preferred_coding.value,
+                                             available)) {
+          preferred_available.push_back(available);
+          break;
+        }
+      }
+    }
+
+    // Step 6. Return preferred-available. [spec text]
+    return preferred_available;
+  }
+};
+
+// https://httpwg.org/http-extensions/draft-ietf-httpbis-variants.html#content-language
+class AcceptLanguageNegotiation final : public ContentNegotiationAlgorithm {
+ public:
+  std::vector<std::string> run(
+      base::span<const std::string> available_values,
+      base::Optional<std::string> request_header_value) override {
+    // Step 1. Let preferred-available be an empty list. [spec text]
+    std::vector<std::string> preferred_available;
+
+    // Step 2. Let preferred-langs be a list of the language-ranges in the
+    // request-value (or the empty list if request-value is null), ordered by
+    // their weight, highest to lowest, as per Section 5.3.1 of [RFC7231]
+    // (omitting any language-range with a weight of 0). If a language-range
+    // lacks a weight, an implementation MAY assign one. [spec text]
+    std::vector<WeightedValue> preferred_langs =
+        ParseRequestHeaderValue(request_header_value);
+
+    // Step 3. For each preferred-lang in preferred-langs: [spec text]
+    for (const WeightedValue& preferred_lang : preferred_langs) {
+      // Step 3.1. If any member of available-values matches preferred-lang,
+      // using either the Basic or Extended Filtering scheme defined in
+      // Section 3.3 of [RFC4647], append those members of available-values to
+      // preferred-available (preserving their order). [spec text]
+      AppendMatchedLanguages(available_values, preferred_lang.value,
+                             &preferred_available);
+    }
+
+    // Step 4. If preferred-available is empty, append the first member of
+    // available-values to preferred-available. This makes the first
+    // available-value the default when none of the client's preferences are
+    // available. [spec text]
+    if (preferred_available.empty() && !available_values.empty())
+      preferred_available.push_back(available_values[0]);
+
+    // Step 5. Return preferred-available. [spec text]
+    return preferred_available;
+  }
+
+ private:
+  // Performs the Basic Filtering (Section 3.3.1 of [RFC4647]).
+  void AppendMatchedLanguages(base::span<const std::string> available_values,
+                              const std::string& preferred_lang,
+                              std::vector<std::string>* output) {
+    if (preferred_lang == "*") {
+      std::copy(available_values.begin(), available_values.end(),
+                std::back_inserter(*output));
+      return;
+    }
+
+    const std::string prefix = preferred_lang + '-';
+    for (const std::string& available : available_values) {
+      if (base::EqualsCaseInsensitiveASCII(preferred_lang, available) ||
+          base::StartsWith(available, prefix,
+                           base::CompareCase::INSENSITIVE_ASCII)) {
+        output->push_back(available);
+      }
+    }
+  }
+};
+
+std::unique_ptr<ContentNegotiationAlgorithm> GetContentNegotiationAlgorithm(
+    const std::string& field_name) {
+  if (field_name == "accept")
+    return std::make_unique<ContentTypeNegotiation>();
+  if (field_name == "accept-encoding")
+    return std::make_unique<AcceptEncodingNegotiation>();
+  if (field_name == "accept-language")
+    return std::make_unique<AcceptLanguageNegotiation>();
+  return nullptr;
+}
+
+// https://httpwg.org/http-extensions/draft-ietf-httpbis-variants.html#variant-key
+base::Optional<http_structured_header::ListOfLists> ParseVariantKey(
+    const base::StringPiece& str,
+    size_t num_variant_axes) {
+  base::Optional<http_structured_header::ListOfLists> parsed =
+      http_structured_header::ParseListOfLists(str);
+  if (!parsed)
+    return parsed;
+  // Each inner-list MUST have the same number of list-members as there are
+  // variant-axes in the representation's Variants header field. If not, the
+  // client MUST treat the representation as having no Variant-Key header field.
+  // [spec text]
+  for (const auto& inner_list : *parsed) {
+    if (inner_list.size() != num_variant_axes)
+      return base::nullopt;
+  }
+  return parsed;
+}
+
+}  // namespace
+
+// Implements "Cache Behaviour" [1] when "stored-responses" is a singleton list
+// containing a response that has "Variants" header whose value is |variants|.
+// [1] https://httpwg.org/http-extensions/draft-ietf-httpbis-variants.html#cache
+std::vector<std::vector<std::string>>
+SignedExchangeRequestMatcher::CacheBehavior(
+    const http_structured_header::ListOfLists& variants,
+    const SignedExchangeRequestMatcher::HeaderMap& request_headers) {
+  // Step 1. If stored-responses is empty, return an empty list. [spec text]
+  // The size of stored-responses is always 1.
+
+  // Step 2. Order stored-responses by the "Date" header field, most recent to
+  // least recent. [spec text]
+  // This is no-op because stored-responses is a single-element list.
+
+  // Step 3. Let sorted-variants be an empty list. [spec text]
+  std::vector<std::vector<std::string>> sorted_variants;
+
+  // Step 4. If the freshest member of stored-responses (as per [RFC7234],
+  // Section 4.2) has one or more "Variants" header field(s) that successfully
+  // parse according to Section 2: [spec text]
+
+  // Step 4.1. Select one member of stored-responses with a "Variants" header
+  // field-value(s) that successfully parses according to Section 2 and let
+  // variants-header be this parsed value. This SHOULD be the most recent
+  // response, but MAY be from an older one as long as it is still fresh.
+  // [spec text]
+  // |variants| is the parsed "Variants" header field value.
+
+  // Step 4.2. For each variant-axis in variants-header: [spec text]
+  for (const std::vector<std::string>& variant_axis : variants) {
+    DCHECK(!variant_axis.empty());
+
+    // Step 4.2.1. If variant-axis' field-name corresponds to the request header
+    // field identified by a content negotiation mechanism that the
+    // implementation supports: [spec text]
+    std::string field_name = base::ToLowerASCII(variant_axis[0]);
+    std::unique_ptr<ContentNegotiationAlgorithm> negotiation_algorithm =
+        GetContentNegotiationAlgorithm(field_name);
+    if (negotiation_algorithm) {
+      // Step 4.2.1.1. Let request-value be the field-value associated with
+      // field-name in incoming-request (after being combined as allowed by
+      // Section 3.2.2 of [RFC7230]), or null if field-name is not in
+      // incoming-request. [spec text]
+      base::Optional<std::string> request_value;
+      auto found = request_headers.find(field_name);
+      if (found != request_headers.end())
+        request_value = found->second;
+      // Step 4.2.1.2. Let sorted-values be the result of running the algorithm
+      // defined by the content negotiation mechanism with request-value and
+      // variant-axis' available-values. [spec text]
+      std::vector<std::string> sorted_values = negotiation_algorithm->run(
+          base::make_span(variant_axis).subspan(1), request_value);
+
+      // Step 4.2.1.3. Append sorted-values to sorted-variants. [spec text]
+      sorted_variants.push_back(std::move(sorted_values));
+    }
+  }
+  // At this point, sorted-variants will be a list of lists, each member of the
+  // top-level list corresponding to a variant-axis in the Variants header
+  // field-value, containing zero or more items indicating available-values
+  // that are acceptable to the client, in order of preference, greatest to
+  // least. [spec text]
+
+  // Step 5. Return result of running Compute Possible Keys (Section 4.1) on
+  // sorted-variants, an empty list and an empty list. [spec text]
+  // Instead of computing the cross product of sorted_variants, this
+  // implementation just returns sorted_variants.
+  return sorted_variants;
+}
+
+// Implements step 3- of
+// https://wicg.github.io/webpackage/loading.html#request-matching
+bool SignedExchangeRequestMatcher::MatchRequest(
+    const SignedExchangeRequestMatcher::HeaderMap& request_headers,
+    const SignedExchangeRequestMatcher::HeaderMap& response_headers) {
+  auto variants_found = response_headers.find(kVariantsHeader);
+  auto variant_key_found = response_headers.find(kVariantKeyHeader);
+
+  // Step 3. If storedExchange's response's header list contains:
+  // - Neither a `Variants` nor a `Variant-Key` header
+  //   Return "match". [spec text]
+  if (variants_found == response_headers.end() &&
+      variant_key_found == response_headers.end()) {
+    return true;
+  }
+  // - A `Variant-Key` header but no `Variants` header
+  //   Return "mismatch". [spec text]
+  if (variants_found == response_headers.end())
+    return false;
+  // - A `Variants` header but no `Variant-Key` header
+  //   Return "mismatch". [spec text]
+  if (variant_key_found == response_headers.end())
+    return false;
+  // - Both a `Variants` and a `Variant-Key` header
+  //   Proceed to the following steps. [spec text]
+
+  // Step 4. If getting `Variants` from storedExchange's response's header list
+  // returns a value that fails to parse according to the instructions for the
+  // Variants Header Field, return "mismatch". [spec text]
+  auto parsed_variants =
+      http_structured_header::ParseListOfLists(variants_found->second);
+  if (!parsed_variants)
+    return false;
+
+  // Step 5. Let acceptableVariantKeys be the result of running the Variants
+  // Cache Behavior on an incoming-request of browserRequest and
+  // stored-responses of a list containing storedExchange's response.
+  // [spec text]
+  std::vector<std::vector<std::string>> sorted_variants =
+      CacheBehavior(*parsed_variants, request_headers);
+
+  // This happens when `Variant` has unknown field names. In such cases,
+  // this algorithm never returns "match", so we do an early return.
+  if (sorted_variants.size() != parsed_variants->size())
+    return false;
+
+  // Step 6. Let variantKeys be the result of getting `Variant-Key` from
+  // storedExchange's response's header list, and parsing it into a list of
+  // lists as described in Variant-Key Header Field. [spec text]
+  auto parsed_variant_key =
+      ParseVariantKey(variant_key_found->second, parsed_variants->size());
+
+  // Step 7. If parsing variantKeys failed, return "mismatch". [spec text]
+  if (!parsed_variant_key)
+    return false;
+
+  // Step 8. If the intersection of acceptableVariantKeys and variantKeys is
+  // empty, return "mismatch". [spec text]
+  // Step 9. Return "match". [spec text]
+
+  // AcceptableVariantKeys is the cross product of sorted_variants. Instead of
+  // computing AcceptableVariantKeys and taking the intersection of it and
+  // variantKeys, we check its equivalent, i.e.: Return "match" if there is a vk
+  // in variantKeys such that for all i, vk[i] is in sorted_variants[i].
+  for (const std::vector<std::string>& vk : *parsed_variant_key) {
+    DCHECK_EQ(vk.size(), sorted_variants.size());
+    size_t i = 0;
+    for (; i < sorted_variants.size(); ++i) {
+      auto found = std::find(sorted_variants[i].begin(),
+                             sorted_variants[i].end(), vk[i]);
+      if (found == sorted_variants[i].end())
+        break;
+    }
+    if (i == sorted_variants.size())
+      return true;
+  }
+  // Otherwise return "mismatch".
+  return false;
+}
+
+}  // namespace content
diff --git a/content/browser/web_package/signed_exchange_request_matcher.h b/content/browser/web_package/signed_exchange_request_matcher.h
new file mode 100644
index 0000000..cfa9271
--- /dev/null
+++ b/content/browser/web_package/signed_exchange_request_matcher.h
@@ -0,0 +1,35 @@
+// 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 CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_REQUEST_MATCHER_H_
+#define CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_REQUEST_MATCHER_H_
+
+#include <map>
+#include <string>
+#include <vector>
+
+#include "base/gtest_prod_util.h"
+#include "content/browser/web_package/http_structured_header.h"
+#include "content/common/content_export.h"
+
+namespace content {
+
+class CONTENT_EXPORT SignedExchangeRequestMatcher {
+ public:
+  // Keys must be lower-cased.
+  using HeaderMap = std::map<std::string, std::string>;
+
+  static bool MatchRequest(const HeaderMap& request_headers,
+                           const HeaderMap& response_headers);
+
+ private:
+  static std::vector<std::vector<std::string>> CacheBehavior(
+      const http_structured_header::ListOfLists& variants,
+      const HeaderMap& request_headers);
+  FRIEND_TEST_ALL_PREFIXES(SignedExchangeRequestMatcherTest, CacheBehavior);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_WEB_PACKAGE_SIGNED_EXCHANGE_REQUEST_MATCHER_H_
diff --git a/content/browser/web_package/signed_exchange_request_matcher_unittest.cc b/content/browser/web_package/signed_exchange_request_matcher_unittest.cc
new file mode 100644
index 0000000..396978f
--- /dev/null
+++ b/content/browser/web_package/signed_exchange_request_matcher_unittest.cc
@@ -0,0 +1,213 @@
+// 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 "content/browser/web_package/signed_exchange_request_matcher.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+constexpr char kVariantsHeader[] = "variants-04";
+constexpr char kVariantKeyHeader[] = "variant-key-04";
+
+TEST(SignedExchangeRequestMatcherTest, CacheBehavior) {
+  const struct TestCase {
+    const char* name;
+    SignedExchangeRequestMatcher::HeaderMap req_headers;
+    http_structured_header::ListOfLists variants;
+    std::vector<std::vector<std::string>> expected;
+  } cases[] = {
+      // Accept
+      {"vanilla content-type",
+       {{"accept", "text/html"}},
+       {{"Accept", "text/html"}},
+       {{"text/html"}}},
+      {"client supports two content-types",
+       {{"accept", "text/html, image/jpeg"}},
+       {{"Accept", "text/html"}},
+       {{"text/html"}}},
+      {"format miss",
+       {{"accept", "image/jpeg"}},
+       {{"Accept", "text/html"}},
+       {{"text/html"}}},
+      {"no format preference", {}, {{"Accept", "text/html"}}, {{"text/html"}}},
+      {"no available format", {{"accept", "text/html"}}, {{"Accept"}}, {{}}},
+      {"accept all types",
+       {{"accept", "*/*"}},
+       {{"Accept", "text/html", "image/jpeg"}},
+       {{"text/html", "image/jpeg"}}},
+      {"accept all subtypes",
+       {{"accept", "image/*"}},
+       {{"Accept", "text/html", "image/jpeg"}},
+       {{"image/jpeg"}}},
+      {"type params match",
+       {{"accept", "text/html;param=bar"}},
+       {{"Accept", "text/html;param=foo", "text/html;param=bar"}},
+       {{"text/html;param=bar"}}},
+      {"type with q value",
+       {{"accept", "text/html;q=0.8;param=foo"}},
+       {{"Accept", "image/jpeg", "text/html;param=foo"}},
+       {{"text/html;param=foo"}}},
+      {"type with zero q value",
+       {{"accept", "text/html;q=0.0, image/jpeg"}},
+       {{"Accept", "text/html", "image/jpeg"}},
+       {{"image/jpeg"}}},
+      {"type with invalid q value",
+       {{"accept", "text/html;q=999, image/jpeg"}},
+       {{"Accept", "text/html", "image/jpeg"}},
+       {{"text/html", "image/jpeg"}}},
+      // Accept-Encoding
+      {"vanilla encoding",
+       {{"accept-encoding", "gzip"}},
+       {{"Accept-Encoding", "gzip"}},
+       {{"gzip", "identity"}}},
+      {"client supports two encodings",
+       {{"accept-encoding", "gzip, br"}},
+       {{"Accept-Encoding", "gzip"}},
+       {{"gzip", "identity"}}},
+      {"two stored, two preferences",
+       {{"accept-encoding", "gzip, br"}},
+       {{"Accept-Encoding", "gzip", "br"}},
+       {{"gzip", "br", "identity"}}},
+      {"no encoding preference",
+       {},
+       {{"Accept-Encoding", "gzip"}},
+       {{"identity"}}},
+      // Accept-Language
+      {"vanilla language",
+       {{"accept-language", "en"}},
+       {{"Accept-Language", "en"}},
+       {{"en"}}},
+      {"multiple languages",
+       {{"accept-language", "en, JA"}},
+       {{"Accept-Language", "en", "fr", "ja"}},
+       {{"en", "ja"}}},
+      {"no language preference",
+       {},
+       {{"Accept-Language", "en", "ja"}},
+       {{"en"}}},
+      {"no available language",
+       {{"accept-language", "en"}},
+       {{"Accept-Language"}},
+       {{}}},
+      {"accept all languages",
+       {{"accept-language", "*"}},
+       {{"Accept-Language", "en", "ja"}},
+       {{"en", "ja"}}},
+      {"language subtag",
+       {{"accept-language", "en"}},
+       {{"Accept-Language", "en-US", "enq"}},
+       {{"en-US"}}},
+      {"language with q values",
+       {{"accept-language", "ja, en;q=0.8"}},
+       {{"Accept-Language", "fr", "en", "ja"}},
+       {{"ja", "en"}}},
+      {"language with zero q value",
+       {{"accept-language", "ja, en;q=0"}},
+       {{"Accept-Language", "fr", "en"}},
+       {{"fr"}}},
+      // Multiple axis
+      {"format and language matches",
+       {{"accept", "text/html"}, {"accept-language", "en"}},
+       {{"Accept", "text/html"}, {"Accept-Language", "en", "fr"}},
+       {{"text/html"}, {"en"}}},
+      {"accept anything",
+       {{"accept", "*/*"}, {"accept-language", "*"}},
+       {{"Accept", "text/html", "image/jpeg"}, {"Accept-Language", "en", "fr"}},
+       {{"text/html", "image/jpeg"}, {"en", "fr"}}},
+      {"unknown field name",
+       {{"accept-language", "en"}, {"unknown", "foo"}},
+       {{"Accept-Language", "en"}, {"Unknown", "foo"}},
+       {{"en"}}},
+  };
+  for (const auto& c : cases) {
+    EXPECT_EQ(c.expected, SignedExchangeRequestMatcher::CacheBehavior(
+                              c.variants, c.req_headers))
+        << c.name;
+  }
+}
+
+TEST(SignedExchangeRequestMatcherTest, MatchRequest) {
+  const struct TestCase {
+    const char* name;
+    SignedExchangeRequestMatcher::HeaderMap req_headers;
+    SignedExchangeRequestMatcher::HeaderMap res_headers;
+    bool should_match;
+  } cases[] = {
+      {"no variants and variant-key", {{"accept", "text/html"}}, {}, true},
+      {"has variants but no variant-key",
+       {{"accept", "text/html"}},
+       {{kVariantsHeader, "Accept; text/html"}},
+       false},
+      {"has variant-key but no variants",
+       {{"accept", "text/html"}},
+       {{kVariantKeyHeader, "text/html"}},
+       false},
+      {"content type matches",
+       {{"accept", "text/html"}},
+       {{kVariantsHeader, "Accept; text/html; image/jpeg"},
+        {kVariantKeyHeader, "text/html"}},
+       true},
+      {"content type misses",
+       {{"accept", "image/jpeg"}},
+       {{kVariantsHeader, "Accept; text/html; image/jpeg"},
+        {kVariantKeyHeader, "text/html"}},
+       false},
+      {"encoding matches",
+       {},
+       {{kVariantsHeader, "Accept-Encoding;gzip;identity"},
+        {kVariantKeyHeader, "identity"}},
+       true},
+      {"encoding misses",
+       {},
+       {{kVariantsHeader, "Accept-Encoding;gzip;identity"},
+        {kVariantKeyHeader, "gzip"}},
+       false},
+      {"language matches",
+       {{"accept-language", "en"}},
+       {{kVariantsHeader, "Accept-Language;en;ja"}, {kVariantKeyHeader, "en"}},
+       true},
+      {"language misses",
+       {{"accept-language", "ja"}},
+       {{kVariantsHeader, "Accept-Language;en;ja"}, {kVariantKeyHeader, "en"}},
+       false},
+      {"content type and language match",
+       {{"accept", "text/html"}, {"accept-language", "en"}},
+       {{kVariantsHeader, "Accept-Language;fr;en, Accept;text/plain;text/html"},
+        {kVariantKeyHeader, "en;text/html"}},
+       true},
+      {"content type matches but language misses",
+       {{"accept", "text/html"}, {"accept-language", "fr"}},
+       {{kVariantsHeader, "Accept-Language;fr;en, Accept;text/plain;text/html"},
+        {kVariantKeyHeader, "en;text/html"}},
+       false},
+      {"language matches but content type misses",
+       {{"accept", "text/plain"}, {"accept-language", "en"}},
+       {{kVariantsHeader, "Accept-Language;fr;en, Accept;text/plain;text/html"},
+        {kVariantKeyHeader, "en;text/html"}},
+       false},
+      {"multiple variant key",
+       {{"accept-encoding", "identity"}, {"accept-language", "fr"}},
+       {{kVariantsHeader, "Accept-Encoding;gzip;br, Accept-Language;en;fr"},
+        {kVariantKeyHeader, "gzip;fr, identity;fr"}},
+       true},
+      {"bad variant key item length",
+       {},
+       {{kVariantsHeader, "Accept;text/html, Accept-Language;en;fr"},
+        {kVariantKeyHeader, "text/html;en, text/html;fr;oops"}},
+       false},
+      {"unknown field name",
+       {{"accept-language", "en"}, {"unknown", "foo"}},
+       {{kVariantsHeader, "Accept-Language;en, Unknown;foo"},
+        {kVariantKeyHeader, "en;foo"}},
+       false},
+  };
+  for (const auto& c : cases) {
+    EXPECT_EQ(c.should_match, SignedExchangeRequestMatcher::MatchRequest(
+                                  c.req_headers, c.res_headers))
+        << c.name;
+  }
+}
+
+}  // namespace content
diff --git a/content/public/app/BUILD.gn b/content/public/app/BUILD.gn
index 5f44e2d..9b73220 100644
--- a/content/public/app/BUILD.gn
+++ b/content/public/app/BUILD.gn
@@ -190,8 +190,8 @@
     ":v8_snapshot_overlay_manifest",
     "//base",
     "//content/public/common:service_names",
-    "//services/content:manifest",
-    "//services/file:manifest",
+    "//services/content/public/cpp:manifest",
+    "//services/file/public/cpp:manifest",
   ]
 
   public_deps = [
@@ -223,18 +223,18 @@
 
   deps = [
     "//base",
-    "//components/services/heap_profiling:manifest",
+    "//components/services/heap_profiling/public/cpp:manifest",
     "//content/public/common:service_names",
     "//media/mojo/services:cdm_manifest",
     "//media/mojo/services:media_manifest",
     "//services/audio/public/cpp:manifest",
-    "//services/data_decoder:manifest",
-    "//services/device:manifest",
-    "//services/media_session:manifest",
-    "//services/metrics:manifest",
-    "//services/network:manifest",
-    "//services/resource_coordinator:manifest",
-    "//services/shape_detection:manifest",
+    "//services/data_decoder/public/cpp:manifest",
+    "//services/device/public/cpp:manifest",
+    "//services/media_session/public/cpp:manifest",
+    "//services/metrics/public/cpp:manifest",
+    "//services/network/public/cpp:manifest",
+    "//services/resource_coordinator/public/cpp:manifest",
+    "//services/shape_detection/public/cpp:manifest",
     "//services/tracing:manifest",
     "//services/video_capture/public/cpp:manifest",
     "//services/viz:manifest",
@@ -251,7 +251,8 @@
   if (is_chromeos) {
     deps += [ "//chromeos/assistant:buildflags" ]
     if (enable_cros_libassistant) {
-      deps += [ "//chromeos/services/assistant/audio_decoder:manifest" ]
+      deps +=
+          [ "//chromeos/services/assistant/public/cpp:audio_decoder_manifest" ]
     }
   }
 }
diff --git a/content/public/app/DEPS b/content/public/app/DEPS
index e896a38..ec2968b 100644
--- a/content/public/app/DEPS
+++ b/content/public/app/DEPS
@@ -11,23 +11,23 @@
 
 specific_include_rules = {
   "content_browser_manifest\.cc": [
-    "+services/content/manifest.h",
-    "+services/file/manifest.h",
+    "+services/content/public/cpp/manifest.h",
+    "+services/file/public/cpp/manifest.h",
   ],
   "content_packaged_services_manifest\.cc": [
     "+chromeos/assistant/buildflags.h",
-    "+chromeos/services/assistant/audio_decoder/manifest.h",
+    "+chromeos/services/assistant/public/cpp/audio_decoder_manifest.h",
     "+components/services/font/public/cpp/manifest.h",
-    "+components/services/heap_profiling/manifest.h",
+    "+components/services/heap_profiling/public/cpp/manifest.h",
     "+media/mojo/services/cdm_manifest.h",
     "+media/mojo/services/media_manifest.h",
-    "+services/data_decoder/manifest.h",
-    "+services/device/manifest.h",
-    "+services/media_session/manifest.h",
-    "+services/metrics/manifest.h",
-    "+services/network/manifest.h",
-    "+services/resource_coordinator/manifest.h",
-    "+services/shape_detection/manifest.h",
+    "+services/data_decoder/public/cpp/manifest.h",
+    "+services/device/public/cpp/manifest.h",
+    "+services/media_session/public/cpp/manifest.h",
+    "+services/metrics/public/cpp/manifest.h",
+    "+services/network/public/cpp/manifest.h",
+    "+services/resource_coordinator/public/cpp/manifest.h",
+    "+services/shape_detection/public/cpp/manifest.h",
     "+services/tracing/manifest.h",
     "+services/viz/manifest.h",
   ],
diff --git a/content/public/app/content_browser_manifest.cc b/content/public/app/content_browser_manifest.cc
index 8960cf9..9b430a1 100644
--- a/content/public/app/content_browser_manifest.cc
+++ b/content/public/app/content_browser_manifest.cc
@@ -6,8 +6,8 @@
 
 #include "base/no_destructor.h"
 #include "content/public/common/service_names.mojom.h"
-#include "services/content/manifest.h"
-#include "services/file/manifest.h"
+#include "services/content/public/cpp/manifest.h"
+#include "services/file/public/cpp/manifest.h"
 #include "services/service_manager/public/cpp/manifest_builder.h"
 
 namespace content {
@@ -120,7 +120,6 @@
           .RequireCapability("file", "file:leveldb")
           .RequireCapability("network", "network_service")
           .RequireCapability("network", "test")
-          .RequireCapability("network", "url_loader")
           .RequireCapability(mojom::kRendererServiceName, "browser")
           .RequireCapability("media", "media:media")
           .RequireCapability("*", "app")
diff --git a/content/public/app/content_packaged_services_manifest.cc b/content/public/app/content_packaged_services_manifest.cc
index e101a5d..6f6280b 100644
--- a/content/public/app/content_packaged_services_manifest.cc
+++ b/content/public/app/content_packaged_services_manifest.cc
@@ -6,19 +6,19 @@
 
 #include "base/no_destructor.h"
 #include "build/build_config.h"
-#include "components/services/heap_profiling/manifest.h"
+#include "components/services/heap_profiling/public/cpp/manifest.h"
 #include "content/public/common/service_names.mojom.h"
 #include "media/mojo/services/cdm_manifest.h"
 #include "media/mojo/services/media_manifest.h"
 #include "services/audio/public/cpp/manifest.h"
-#include "services/data_decoder/manifest.h"
-#include "services/device/manifest.h"
-#include "services/media_session/manifest.h"
-#include "services/metrics/manifest.h"
-#include "services/network/manifest.h"
-#include "services/resource_coordinator/manifest.h"
+#include "services/data_decoder/public/cpp/manifest.h"
+#include "services/device/public/cpp/manifest.h"
+#include "services/media_session/public/cpp/manifest.h"
+#include "services/metrics/public/cpp/manifest.h"
+#include "services/network/public/cpp/manifest.h"
+#include "services/resource_coordinator/public/cpp/manifest.h"
 #include "services/service_manager/public/cpp/manifest_builder.h"
-#include "services/shape_detection/manifest.h"
+#include "services/shape_detection/public/cpp/manifest.h"
 #include "services/tracing/manifest.h"
 #include "services/video_capture/public/cpp/manifest.h"
 #include "services/viz/manifest.h"
@@ -30,7 +30,7 @@
 #if defined(OS_CHROMEOS)
 #include "chromeos/assistant/buildflags.h"
 #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
-#include "chromeos/services/assistant/audio_decoder/manifest.h"
+#include "chromeos/services/assistant/public/cpp/audio_decoder_manifest.h"  // nogncheck
 #endif  // BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
 #endif  // defined(OS_CHROMEOS)
 
@@ -72,7 +72,8 @@
 #endif
 #if defined(OS_CHROMEOS)
 #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
-        .PackageService(assistant_audio_decoder::GetManifest())
+        // TODO(https://crbug.com/929340): This doesn't belong here!
+        .PackageService(chromeos::assistant::GetAudioDecoderManifest())
 #endif  // BUILDFLAG(ENABLE_CROS_LIBASSISTANT)
 #endif  // defined(OS_CHROMEOS)
         .Build()
diff --git a/content/public/browser/devtools_manager_delegate.cc b/content/public/browser/devtools_manager_delegate.cc
index be5ffe2..f313b48 100644
--- a/content/public/browser/devtools_manager_delegate.cc
+++ b/content/public/browser/devtools_manager_delegate.cc
@@ -59,13 +59,12 @@
 void DevToolsManagerDelegate::ClientDetached(DevToolsAgentHost* agent_host,
                                              DevToolsAgentHostClient* client) {}
 
-void DevToolsManagerDelegate::HandleCommand(
-    DevToolsAgentHost* agent_host,
-    DevToolsAgentHostClient* client,
-    std::unique_ptr<base::DictionaryValue> command,
-    const std::string& message,
-    NotHandledCallback callback) {
-  std::move(callback).Run(std::move(command), message);
+void DevToolsManagerDelegate::HandleCommand(DevToolsAgentHost* agent_host,
+                                            DevToolsAgentHostClient* client,
+                                            const std::string& method,
+                                            const std::string& message,
+                                            NotHandledCallback callback) {
+  std::move(callback).Run(message);
 }
 
 std::string DevToolsManagerDelegate::GetDiscoveryPageHTML() {
diff --git a/content/public/browser/devtools_manager_delegate.h b/content/public/browser/devtools_manager_delegate.h
index a31878d1..4b5ba76 100644
--- a/content/public/browser/devtools_manager_delegate.h
+++ b/content/public/browser/devtools_manager_delegate.h
@@ -13,10 +13,6 @@
 #include "content/public/browser/devtools_agent_host.h"
 #include "url/gurl.h"
 
-namespace base {
-class DictionaryValue;
-}
-
 namespace content {
 
 class DevToolsAgentHostClient;
@@ -71,12 +67,10 @@
                               DevToolsAgentHostClient* client);
 
   // Call callback if command was not handled.
-  using NotHandledCallback =
-      base::OnceCallback<void(std::unique_ptr<base::DictionaryValue>,
-                              const std::string&)>;
+  using NotHandledCallback = base::OnceCallback<void(const std::string&)>;
   virtual void HandleCommand(DevToolsAgentHost* agent_host,
                              DevToolsAgentHostClient* client,
-                             std::unique_ptr<base::DictionaryValue> command,
+                             const std::string& method,
                              const std::string& message,
                              NotHandledCallback callback);
 
diff --git a/content/public/test/browser_test_base.cc b/content/public/test/browser_test_base.cc
index 5bb0e93..2ecaf78 100644
--- a/content/public/test/browser_test_base.cc
+++ b/content/public/test/browser_test_base.cc
@@ -66,12 +66,6 @@
 #include "base/process/process_handle.h"
 #endif
 
-#if defined(OS_CHROMEOS)
-#include "content/public/browser/network_service_instance.h"
-#include "net/base/network_change_notifier.h"
-#include "net/base/network_change_notifier_chromeos.h"
-#endif
-
 #if defined(USE_AURA)
 #include "content/browser/compositor/image_transport_factory.h"
 #include "ui/aura/test/event_generator_delegate_aura.h"  // nogncheck
@@ -393,32 +387,6 @@
     signal(SIGTERM, DumpStackTraceSignalHandler);
 #endif  // defined(OS_POSIX)
 
-#if defined(OS_CHROMEOS)
-  // Manually set the connection type since ChromeOS's NetworkChangeNotifier
-  // implementation relies on some other class controlling it (normally
-  // NetworkChangeManagerClient), which may not be set up in all browser tests.
-  net::NetworkChangeNotifierChromeos* network_change_notifier =
-      static_cast<net::NetworkChangeNotifierChromeos*>(
-          content::GetNetworkChangeNotifier());
-  network_change_notifier->OnConnectionChanged(
-      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
-  // If the network service is enabled, set the connection type for its
-  // NetworkChangeNotifier instance as well.
-  if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
-      !IsNetworkServiceRunningInProcess()) {
-    network::mojom::NetworkChangeManagerPtr manager_ptr;
-    network::mojom::NetworkChangeManagerRequest request(
-        mojo::MakeRequest(&manager_ptr));
-    GetNetworkService()->GetNetworkChangeManager(std::move(request));
-    manager_ptr->OnNetworkChanged(
-        /*dns_changed=*/false, /*ip_address_changed=*/false,
-        /*connection_type_changed=*/true,
-        network::mojom::ConnectionType::CONNECTION_ETHERNET,
-        /*connection_subtype_changed=*/false,
-        network::mojom::ConnectionSubtype::SUBTYPE_UNKNOWN);
-  }
-#endif
-
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kEnableTracing)) {
     base::trace_event::TraceConfig trace_config(
diff --git a/content/public/test/content_browser_test.cc b/content/public/test/content_browser_test.cc
index 2ab346c2..0d3f512 100644
--- a/content/public/test/content_browser_test.cc
+++ b/content/public/test/content_browser_test.cc
@@ -33,6 +33,10 @@
 #include "ui/base/ime/input_method_initializer.h"
 #endif
 
+#if defined(OS_CHROMEOS)
+#include "content/public/test/network_connection_change_simulator.h"
+#endif
+
 #if defined(USE_AURA) && defined(TOOLKIT_VIEWS)
 #include "ui/views/test/widget_test_api.h"  // nogncheck
 #endif
@@ -116,6 +120,11 @@
 }
 
 void ContentBrowserTest::PreRunTestOnMainThread() {
+#if defined(OS_CHROMEOS)
+  NetworkConnectionChangeSimulator network_change_simulator;
+  network_change_simulator.InitializeChromeosConnectionType();
+#endif
+
   if (!switches::IsRunWebTestsSwitchPresent()) {
     CHECK_EQ(Shell::windows().size(), 1u);
     shell_ = Shell::windows()[0];
diff --git a/content/public/test/network_connection_change_simulator.cc b/content/public/test/network_connection_change_simulator.cc
index 14652fe..a334ced 100644
--- a/content/public/test/network_connection_change_simulator.cc
+++ b/content/public/test/network_connection_change_simulator.cc
@@ -4,18 +4,23 @@
 
 #include "content/public/test/network_connection_change_simulator.h"
 
+#include <utility>
+
 #include "base/bind.h"
-#include "base/feature_list.h"
 #include "base/run_loop.h"
 #include "content/public/browser/network_service_instance.h"
+#include "content/public/common/network_service_util.h"
 #include "content/public/common/service_manager_connection.h"
 #include "content/public/common/service_names.mojom.h"
-#include "content/public/test/browser_test_utils.h"
 #include "net/base/network_change_notifier.h"
-#include "services/network/public/cpp/features.h"
 #include "services/network/public/mojom/network_service_test.mojom.h"
 #include "services/service_manager/public/cpp/connector.h"
 
+#if defined(OS_CHROMEOS)
+#include "net/base/network_change_notifier_chromeos.h"
+#include "services/network/public/mojom/network_service.mojom.h"
+#endif
+
 namespace content {
 
 // SetConnectionType will block until the network connection changes, and
@@ -30,6 +35,33 @@
 NetworkConnectionChangeSimulator::NetworkConnectionChangeSimulator() = default;
 NetworkConnectionChangeSimulator::~NetworkConnectionChangeSimulator() = default;
 
+#if defined(OS_CHROMEOS)
+void NetworkConnectionChangeSimulator::InitializeChromeosConnectionType() {
+  // Manually set the connection type since ChromeOS's NetworkChangeNotifier
+  // implementation relies on some other class controlling it (normally
+  // NetworkChangeManagerClient), which isn't used on content/.
+  net::NetworkChangeNotifierChromeos* network_change_notifier =
+      static_cast<net::NetworkChangeNotifierChromeos*>(
+          content::GetNetworkChangeNotifier());
+  network_change_notifier->OnConnectionChanged(
+      net::NetworkChangeNotifier::CONNECTION_ETHERNET);
+  // If the network service is enabled, set the connection type for its
+  // NetworkChangeNotifier instance as well.
+  if (IsOutOfProcessNetworkService()) {
+    network::mojom::NetworkChangeManagerPtr manager_ptr;
+    network::mojom::NetworkChangeManagerRequest request(
+        mojo::MakeRequest(&manager_ptr));
+    GetNetworkService()->GetNetworkChangeManager(std::move(request));
+    manager_ptr->OnNetworkChanged(
+        /*dns_changed=*/false, /*ip_address_changed=*/false,
+        /*connection_type_changed=*/true,
+        network::mojom::ConnectionType::CONNECTION_ETHERNET,
+        /*connection_subtype_changed=*/false,
+        network::mojom::ConnectionSubtype::SUBTYPE_UNKNOWN);
+  }
+}
+#endif
+
 void NetworkConnectionChangeSimulator::SetConnectionType(
     network::mojom::ConnectionType type) {
   network::NetworkConnectionTracker* network_connection_tracker =
@@ -60,8 +92,7 @@
 // static
 void NetworkConnectionChangeSimulator::SimulateNetworkChange(
     network::mojom::ConnectionType type) {
-  if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
-      !IsNetworkServiceRunningInProcess()) {
+  if (IsOutOfProcessNetworkService()) {
     network::mojom::NetworkServiceTestPtr network_service_test;
     ServiceManagerConnection::GetForProcess()->GetConnector()->BindInterface(
         mojom::kNetworkServiceName, &network_service_test);
diff --git a/content/public/test/network_connection_change_simulator.h b/content/public/test/network_connection_change_simulator.h
index 2e1fb25..3222885 100644
--- a/content/public/test/network_connection_change_simulator.h
+++ b/content/public/test/network_connection_change_simulator.h
@@ -21,6 +21,12 @@
   NetworkConnectionChangeSimulator();
   ~NetworkConnectionChangeSimulator() override;
 
+#if defined(OS_CHROMEOS)
+  // Initializes the ChromeOS network connection type.
+  // This should be used in tests that don't have a DBus set up.
+  void InitializeChromeosConnectionType();
+#endif
+
   // Synchronously sets the connection type.
   void SetConnectionType(network::mojom::ConnectionType connection_type);
 
diff --git a/content/renderer/pepper/fullscreen_container.h b/content/renderer/pepper/fullscreen_container.h
index 2855b9e..2810d0b 100644
--- a/content/renderer/pepper/fullscreen_container.h
+++ b/content/renderer/pepper/fullscreen_container.h
@@ -20,12 +20,6 @@
 // plugins, that only handles painting.
 class FullscreenContainer {
  public:
-  // Invalidates the full plugin region.
-  virtual void Invalidate() = 0;
-
-  // Invalidates a partial region of the plugin.
-  virtual void InvalidateRect(const blink::WebRect&) = 0;
-
   // Scrolls a partial region of the plugin in the given direction.
   virtual void ScrollRect(int dx, int dy, const blink::WebRect&) = 0;
 
diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc
index 37d751c..553efc8 100644
--- a/content/renderer/pepper/pepper_plugin_instance_impl.cc
+++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc
@@ -730,10 +730,8 @@
 
 void PepperPluginInstanceImpl::InvalidateRect(const gfx::Rect& rect) {
   if (fullscreen_container_) {
-    if (rect.IsEmpty())
-      fullscreen_container_->Invalidate();
-    else
-      fullscreen_container_->InvalidateRect(rect);
+    // The fullscreen container uses a composited layer, which we invalidate
+    // directly below via SetNeedsDisplay().
   } else {
     if (!container_ || view_data_.rect.size.width == 0 ||
         view_data_.rect.size.height == 0)
diff --git a/content/renderer/render_widget_fullscreen_pepper.cc b/content/renderer/render_widget_fullscreen_pepper.cc
index 9774ed67..99cc4ea 100644
--- a/content/renderer/render_widget_fullscreen_pepper.cc
+++ b/content/renderer/render_widget_fullscreen_pepper.cc
@@ -155,7 +155,6 @@
     size_ = size;
     WebRect plugin_rect(0, 0, size_.width, size_.height);
     widget_->plugin()->ViewChanged(plugin_rect, plugin_rect, plugin_rect);
-    widget_->Invalidate();
   }
 
   void ThemeChanged() override { NOTIMPLEMENTED(); }
@@ -309,14 +308,6 @@
 RenderWidgetFullscreenPepper::~RenderWidgetFullscreenPepper() {
 }
 
-void RenderWidgetFullscreenPepper::Invalidate() {
-  InvalidateRect(gfx::Rect(size()));
-}
-
-void RenderWidgetFullscreenPepper::InvalidateRect(const blink::WebRect& rect) {
-  DidInvalidateRect(rect);
-}
-
 void RenderWidgetFullscreenPepper::ScrollRect(
     int dx, int dy, const blink::WebRect& rect) {
 }
diff --git a/content/renderer/render_widget_fullscreen_pepper.h b/content/renderer/render_widget_fullscreen_pepper.h
index c6b17e5..687ac65d 100644
--- a/content/renderer/render_widget_fullscreen_pepper.h
+++ b/content/renderer/render_widget_fullscreen_pepper.h
@@ -40,8 +40,6 @@
       mojom::WidgetRequest widget_request);
 
   // pepper::FullscreenContainer API.
-  void Invalidate() override;
-  void InvalidateRect(const blink::WebRect& rect) override;
   void ScrollRect(int dx, int dy, const blink::WebRect& rect) override;
   void Destroy() override;
   void PepperDidChangeCursor(const blink::WebCursorInfo& cursor) override;
diff --git a/content/shell/test_runner/web_view_test_proxy.cc b/content/shell/test_runner/web_view_test_proxy.cc
index 362b904..c11b977 100644
--- a/content/shell/test_runner/web_view_test_proxy.cc
+++ b/content/shell/test_runner/web_view_test_proxy.cc
@@ -29,9 +29,6 @@
       widget_test_client_(widget_test_client),
       render_widget_(render_widget) {}
 
-void ProxyWebWidgetClient::DidInvalidateRect(const blink::WebRect& r) {
-  base_class_widget_client_->DidInvalidateRect(r);
-}
 void ProxyWebWidgetClient::ScheduleAnimation() {
   // When using threaded compositing, have the RenderWidget schedule a request
   // for a frame, as we use the compositor's scheduler. Otherwise the testing
diff --git a/content/shell/test_runner/web_view_test_proxy.h b/content/shell/test_runner/web_view_test_proxy.h
index 185f9c5..8d6e9e0 100644
--- a/content/shell/test_runner/web_view_test_proxy.h
+++ b/content/shell/test_runner/web_view_test_proxy.h
@@ -59,7 +59,6 @@
                        content::RenderWidget* render_widget);
 
   // blink::WebWidgetClient implementation.
-  void DidInvalidateRect(const blink::WebRect&) override;
   void ScheduleAnimation() override;
   void IntrinsicSizingInfoChanged(
       const blink::WebIntrinsicSizingInfo&) override;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 8542e73..f4f11e1 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1676,6 +1676,7 @@
     "../browser/web_package/signed_exchange_loader_unittest.cc",
     "../browser/web_package/signed_exchange_prefetch_metric_recorder_unittest.cc",
     "../browser/web_package/signed_exchange_prologue_unittest.cc",
+    "../browser/web_package/signed_exchange_request_matcher_unittest.cc",
     "../browser/web_package/signed_exchange_signature_header_field_unittest.cc",
     "../browser/web_package/signed_exchange_signature_verifier_unittest.cc",
     "../browser/web_package/signed_exchange_utils_unittest.cc",
diff --git a/content/test/gpu/gpu_tests/gpu_integration_test.py b/content/test/gpu/gpu_tests/gpu_integration_test.py
index a5077956..29552c7 100644
--- a/content/test/gpu/gpu_tests/gpu_integration_test.py
+++ b/content/test/gpu/gpu_tests/gpu_integration_test.py
@@ -77,6 +77,7 @@
     # interference with the test results.
     browser_args.append(
       '--disable-gpu-process-for-dx12-vulkan-info-collection')
+
     # Append the new arguments.
     browser_options.AppendExtraBrowserArgs(browser_args)
     cls._last_launched_browser_args = set(browser_args)
diff --git a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
index 074f245..e5d308cfe 100644
--- a/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl2_conformance_expectations.py
@@ -892,8 +892,6 @@
         ['linux', 'nvidia'], bug=709351)
     self.Fail('conformance2/rendering/framebuffer-texture-level1.html',
         ['linux', 'nvidia', 'opengl'], bug=680278)
-    self.Fail('conformance2/rendering/multisampling-fragment-evaluation.html',
-        ['linux', 'nvidia', 'no_passthrough'], bug=682815)
     self.Fail('conformance2/textures/image/' +
         'tex-3d-rg8ui-rg_integer-unsigned_byte.html',
         ['linux', ('nvidia', 0xf02)], bug=680282)
diff --git a/device/fido/OWNERS b/device/fido/OWNERS
index 6e1ff3c..2079630c 100644
--- a/device/fido/OWNERS
+++ b/device/fido/OWNERS
@@ -3,21 +3,17 @@
 # General, esp chrome/ UI and Android integration.
 kpaulhamus@chromium.org
 
-# General, esp U2F and CTAP2 code.
-hongjunchoi@chromium.org
-
 # TouchID, Windows Hello.
-martinkr@chromium.org
-
-# Bluetooth.
-jdoerrie@chromium.org
+martinkr@google.com
+martinkr@chromium.org # prefer @google.com
 
 # Attestation and legacy U2F implementation.
 agl@chromium.org
 
-# Emeritus; for occasional reviews, esp those in the depths of view & frame
-# lifetimes.
-engedy@chromium.org
+# Emeriti; for occasional reviews
+engedy@chromium.org # esp. view & frame lifetimes
+jdoerrie@chromium.org # Bluetooth
+hongjunchoi@chromium.org # CTAP2 implementation
 
 # TEAM: identity-dev@chromium.org
 # COMPONENT: Blink>WebAuthentication
diff --git a/device/fido/ctap_make_credential_request.h b/device/fido/ctap_make_credential_request.h
index 8050054..12b72d5 100644
--- a/device/fido/ctap_make_credential_request.h
+++ b/device/fido/ctap_make_credential_request.h
@@ -81,6 +81,7 @@
   const base::Optional<std::vector<uint8_t>>& pin_auth() const {
     return pin_auth_;
   }
+  const base::Optional<uint8_t>& pin_protocol() const { return pin_protocol_; }
 
   void set_is_u2f_only(bool is_u2f_only) { is_u2f_only_ = is_u2f_only; }
   bool is_u2f_only() { return is_u2f_only_; }
diff --git a/device/fido/fido_constants.h b/device/fido/fido_constants.h
index 02cc5b4..85cfa30 100644
--- a/device/fido/fido_constants.h
+++ b/device/fido/fido_constants.h
@@ -105,7 +105,7 @@
   kCtap2ErrUserActionPending = 0x23,
   kCtap2ErrOperationPending = 0x24,
   kCtap2ErrNoOperations = 0x25,
-  kCtap2ErrUnsupportedAlgorithms = 0x26,
+  kCtap2ErrUnsupportedAlgorithm = 0x26,
   kCtap2ErrOperationDenied = 0x27,
   kCtap2ErrKeyStoreFull = 0x28,
   kCtap2ErrNotBusy = 0x29,
@@ -156,7 +156,7 @@
           CtapDeviceResponseCode::kCtap2ErrUserActionPending,
           CtapDeviceResponseCode::kCtap2ErrOperationPending,
           CtapDeviceResponseCode::kCtap2ErrNoOperations,
-          CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithms,
+          CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm,
           CtapDeviceResponseCode::kCtap2ErrOperationDenied,
           CtapDeviceResponseCode::kCtap2ErrKeyStoreFull,
           CtapDeviceResponseCode::kCtap2ErrNotBusy,
diff --git a/device/fido/mac/make_credential_operation.mm b/device/fido/mac/make_credential_operation.mm
index 8c81fc5..be3d8e5 100644
--- a/device/fido/mac/make_credential_operation.mm
+++ b/device/fido/mac/make_credential_operation.mm
@@ -64,7 +64,7 @@
   if (!std::any_of(key_params.begin(), key_params.end(), is_es256)) {
     DVLOG(1) << "No supported algorithm found.";
     std::move(callback())
-        .Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithms,
+        .Run(CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm,
              base::nullopt);
     return;
   }
diff --git a/device/fido/virtual_ctap2_device.cc b/device/fido/virtual_ctap2_device.cc
index d1fe3d50..c3371c6b 100644
--- a/device/fido/virtual_ctap2_device.cc
+++ b/device/fido/virtual_ctap2_device.cc
@@ -50,28 +50,87 @@
                                        data.value_or(std::vector<uint8_t>{}))));
 }
 
-bool AreMakeCredentialOptionsValid(const AuthenticatorSupportedOptions& options,
-                                   const CtapMakeCredentialRequest& request) {
-  if (request.resident_key_required() && !options.supports_resident_key)
-    return false;
+// CheckUserVerification implements the first, common steps of
+// makeCredential and getAssertion from the CTAP2 spec.
+CtapDeviceResponseCode CheckUserVerification(
+    bool is_make_credential,
+    const AuthenticatorSupportedOptions& options,
+    const base::Optional<std::vector<uint8_t>>& pin_auth,
+    const base::Optional<uint8_t>& pin_protocol,
+    UserVerificationRequirement user_verification,
+    base::RepeatingCallback<void(void)> simulate_press_callback,
+    bool* out_user_verified) {
+  // The following quotes are from the CTAP2 spec:
 
-  return request.user_verification() !=
-             UserVerificationRequirement::kRequired ||
-         options.user_verification_availability ==
-             AuthenticatorSupportedOptions::UserVerificationAvailability::
-                 kSupportedAndConfigured;
-}
+  // 1. "If authenticator supports clientPin and platform sends a zero length
+  // pinAuth, wait for user touch and then return either CTAP2_ERR_PIN_NOT_SET
+  // if pin is not set or CTAP2_ERR_PIN_INVALID if pin has been set."
+  const bool supports_pin =
+      options.client_pin_availability !=
+      AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported;
+  if (supports_pin && pin_auth && pin_auth->empty()) {
+    if (simulate_press_callback) {
+      simulate_press_callback.Run();
+    }
+    switch (options.client_pin_availability) {
+      case AuthenticatorSupportedOptions::ClientPinAvailability::
+          kSupportedAndPinSet:
+        return CtapDeviceResponseCode::kCtap2ErrPinInvalid;
+      case AuthenticatorSupportedOptions::ClientPinAvailability::
+          kSupportedButPinNotSet:
+        return CtapDeviceResponseCode::kCtap2ErrPinNotSet;
+      case AuthenticatorSupportedOptions::ClientPinAvailability::kNotSupported:
+        NOTREACHED();
+    }
+  }
 
-bool AreGetAssertionOptionsValid(const AuthenticatorSupportedOptions& options,
-                                 const CtapGetAssertionRequest& request) {
-  if (request.user_presence_required() && !options.user_presence_required)
-    return false;
+  // 2. "If authenticator supports clientPin and pinAuth parameter is present
+  // and the pinProtocol is not supported, return CTAP2_ERR_PIN_AUTH_INVALID
+  // error."
+  if (supports_pin && pin_auth &&
+      (!pin_protocol || *pin_protocol != 1)) {
+    return CtapDeviceResponseCode::kCtap2ErrPinInvalid;
+  }
 
-  return request.user_verification() !=
-             UserVerificationRequirement::kRequired ||
-         options.user_verification_availability ==
-             AuthenticatorSupportedOptions::UserVerificationAvailability::
-                 kSupportedAndConfigured;
+  // 3. "If authenticator is not protected by some form of user verification and
+  // platform has set "uv" or pinAuth to get the user verification, return
+  // CTAP2_ERR_INVALID_OPTION."
+  const bool can_do_uv =
+      options.user_verification_availability ==
+          AuthenticatorSupportedOptions::UserVerificationAvailability::
+              kSupportedAndConfigured ||
+      options.client_pin_availability ==
+          AuthenticatorSupportedOptions::ClientPinAvailability::
+              kSupportedAndPinSet;
+  if (!can_do_uv &&
+      (user_verification == UserVerificationRequirement::kRequired ||
+       pin_auth)) {
+    return CtapDeviceResponseCode::kCtap2ErrInvalidOption;
+  }
+
+  // Step 4.
+  bool uv = false;
+  if (can_do_uv) {
+    if (user_verification == UserVerificationRequirement::kRequired) {
+      // Internal UV is assumed to always succeed.
+      if (simulate_press_callback) {
+        simulate_press_callback.Run();
+      }
+      uv = true;
+    }
+
+    if (pin_auth) {
+      DCHECK(pin_protocol && *pin_protocol == 1);
+      // The pin_auth argument is assumed to be correct.
+      uv = true;
+    }
+
+    if (is_make_credential && !uv) {
+      return CtapDeviceResponseCode::kCtap2ErrPinRequired;
+    }
+  }
+
+  return CtapDeviceResponseCode::kSuccess;
 }
 
 // Checks that whether the received MakeCredential request includes EA256
@@ -274,30 +333,43 @@
   CtapMakeCredentialRequest request = std::get<0>(*request_and_hash);
   CtapMakeCredentialRequest::ClientDataHash client_data_hash =
       std::get<1>(*request_and_hash);
+  const AuthenticatorSupportedOptions& options = device_info_.options();
 
-  if (!AreMakeCredentialOptionsValid(device_info_.options(), request) ||
-      !AreMakeCredentialParamsValid(request)) {
-    DLOG(ERROR) << "Virtual CTAP2 device does not support options required by "
-                   "the request.";
-    return CtapDeviceResponseCode::kCtap2ErrOther;
+  bool user_verified;
+  const CtapDeviceResponseCode uv_error = CheckUserVerification(
+      true /* is makeCredential */, options, request.pin_auth(),
+      request.pin_protocol(), request.user_verification(),
+      mutable_state()->simulate_press_callback, &user_verified);
+  if (uv_error != CtapDeviceResponseCode::kSuccess) {
+    return uv_error;
   }
 
-  // Client pin is not supported.
-  if (request.pin_auth()) {
-    DLOG(ERROR) << "Virtual CTAP2 device does not support client pin.";
-    return CtapDeviceResponseCode::kCtap2ErrPinInvalid;
-  }
-
-  // Check for already registered credentials.
+  // 6. Check for already registered credentials.
   const auto rp_id_hash =
       fido_parsing_utils::CreateSHA256Hash(request.rp().rp_id());
   if (request.exclude_list()) {
     for (const auto& excluded_credential : *request.exclude_list()) {
-      if (FindRegistrationData(excluded_credential.id(), rp_id_hash))
+      if (FindRegistrationData(excluded_credential.id(), rp_id_hash)) {
+        if (mutable_state()->simulate_press_callback) {
+          mutable_state()->simulate_press_callback.Run();
+        }
         return CtapDeviceResponseCode::kCtap2ErrCredentialExcluded;
+      }
     }
   }
 
+  // Step 7.
+  if (!AreMakeCredentialParamsValid(request)) {
+    DLOG(ERROR) << "Virtual CTAP2 device does not support options required by "
+                   "the request.";
+    return CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm;
+  }
+
+  // Step 8.
+  if (request.resident_key_required() && !options.supports_resident_key) {
+    return CtapDeviceResponseCode::kCtap2ErrUnsupportedOption;
+  }
+
   // Create key to register.
   // Note: Non-deterministic, you need to mock this out if you rely on
   // deterministic behavior.
@@ -331,7 +403,7 @@
   }
 
   auto authenticator_data = ConstructAuthenticatorData(
-      rp_id_hash, 01ul, std::move(attested_credential_data),
+      rp_id_hash, user_verified, 01ul, std::move(attested_credential_data),
       std::move(extensions));
   auto sign_buffer =
       ConstructSignatureBuffer(authenticator_data, client_data_hash);
@@ -373,6 +445,16 @@
   CtapGetAssertionRequest request = std::get<0>(*request_and_hash);
   CtapGetAssertionRequest::ClientDataHash client_data_hash =
       std::get<1>(*request_and_hash);
+  const AuthenticatorSupportedOptions& options = device_info_.options();
+
+  bool user_verified;
+  const CtapDeviceResponseCode uv_error = CheckUserVerification(
+      false /* not makeCredential */, options, request.pin_auth(),
+      request.pin_protocol(), request.user_verification(),
+      mutable_state()->simulate_press_callback, &user_verified);
+  if (uv_error != CtapDeviceResponseCode::kSuccess) {
+    return uv_error;
+  }
 
   // Resident keys are not supported.
   if (!request.allow_list() || request.allow_list()->empty()) {
@@ -381,17 +463,6 @@
     return CtapDeviceResponseCode::kCtap2ErrNoCredentials;
   }
 
-  // Client pin option is not supported.
-  if (request.pin_auth()) {
-    DLOG(ERROR) << "Virtual CTAP2 device does not support client pin.";
-    return CtapDeviceResponseCode::kCtap2ErrOther;
-  }
-
-  if (!AreGetAssertionOptionsValid(device_info_.options(), request)) {
-    DLOG(ERROR) << "Unsupported options required from the request.";
-    return CtapDeviceResponseCode::kCtap2ErrOther;
-  }
-
   const auto rp_id_hash = fido_parsing_utils::CreateSHA256Hash(request.rp_id());
 
   RegistrationData* found_data = nullptr;
@@ -409,7 +480,8 @@
 
   found_data->counter++;
   auto authenticator_data = ConstructAuthenticatorData(
-      rp_id_hash, found_data->counter, base::nullopt, base::nullopt);
+      rp_id_hash, user_verified, found_data->counter, base::nullopt,
+      base::nullopt);
   auto signature_buffer =
       ConstructSignatureBuffer(authenticator_data, client_data_hash);
 
@@ -432,14 +504,16 @@
 
 AuthenticatorData VirtualCtap2Device::ConstructAuthenticatorData(
     base::span<const uint8_t, kRpIdHashLength> rp_id_hash,
+    bool user_verified,
     uint32_t current_signature_count,
     base::Optional<AttestedCredentialData> attested_credential_data,
     base::Optional<cbor::Value> extensions) {
   uint8_t flag =
       base::strict_cast<uint8_t>(AuthenticatorData::Flag::kTestOfUserPresence);
-  std::array<uint8_t, kSignCounterLength> signature_counter;
-
-  // Constructing AuthenticatorData for registration operation.
+  if (user_verified) {
+    flag |= base::strict_cast<uint8_t>(
+        AuthenticatorData::Flag::kTestOfUserVerification);
+  }
   if (attested_credential_data)
     flag |= base::strict_cast<uint8_t>(AuthenticatorData::Flag::kAttestation);
   if (extensions) {
@@ -447,6 +521,7 @@
         AuthenticatorData::Flag::kExtensionDataIncluded);
   }
 
+  std::array<uint8_t, kSignCounterLength> signature_counter;
   signature_counter[0] = (current_signature_count >> 24) & 0xff;
   signature_counter[1] = (current_signature_count >> 16) & 0xff;
   signature_counter[2] = (current_signature_count >> 8) & 0xff;
diff --git a/device/fido/virtual_ctap2_device.h b/device/fido/virtual_ctap2_device.h
index fab7d8d..9925fb5 100644
--- a/device/fido/virtual_ctap2_device.h
+++ b/device/fido/virtual_ctap2_device.h
@@ -53,6 +53,7 @@
 
   AuthenticatorData ConstructAuthenticatorData(
       base::span<const uint8_t, kRpIdHashLength> rp_id_hash,
+      bool user_verified,
       uint32_t current_signature_count,
       base::Optional<AttestedCredentialData> attested_credential_data,
       base::Optional<cbor::Value> extensions);
diff --git a/device/fido/win/type_conversions.cc b/device/fido/win/type_conversions.cc
index 20b94a76..299ed74 100644
--- a/device/fido/win/type_conversions.cc
+++ b/device/fido/win/type_conversions.cc
@@ -216,7 +216,7 @@
           {L"ConstraintError",
            CtapDeviceResponseCode::kCtap2ErrUnsupportedOption},
           {L"NotSupportedError",
-           CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithms},
+           CtapDeviceResponseCode::kCtap2ErrUnsupportedAlgorithm},
           {L"NotAllowedError",
            CtapDeviceResponseCode::kCtap2ErrOperationDenied},
           {L"UnknownError", CtapDeviceResponseCode::kCtap2ErrOther},
diff --git a/extensions/shell/test/shell_test.cc b/extensions/shell/test/shell_test.cc
index 40b156b..888a5351 100644
--- a/extensions/shell/test/shell_test.cc
+++ b/extensions/shell/test/shell_test.cc
@@ -16,6 +16,10 @@
 #include "extensions/shell/browser/shell_extension_system.h"
 #include "ui/base/ui_base_features.h"
 
+#if defined(OS_CHROMEOS)
+#include "content/public/test/network_connection_change_simulator.h"
+#endif
+
 namespace extensions {
 
 AppShellTest::AppShellTest()
@@ -39,6 +43,11 @@
 }
 
 void AppShellTest::PreRunTestOnMainThread() {
+#if defined(OS_CHROMEOS)
+  content::NetworkConnectionChangeSimulator network_change_simulator;
+  network_change_simulator.InitializeChromeosConnectionType();
+#endif
+
   browser_context_ = ShellContentBrowserClient::Get()->GetBrowserContext();
 
   extension_system_ = static_cast<ShellExtensionSystem*>(
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 33d198c..9974be5 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -390,7 +390,6 @@
     "command_buffer/service/memory_program_cache_unittest.cc",
     "command_buffer/service/mocks.cc",
     "command_buffer/service/mocks.h",
-    "command_buffer/service/multi_draw_manager_unittest.cc",
     "command_buffer/service/passthrough_program_cache_unittest.cc",
     "command_buffer/service/path_manager_unittest.cc",
     "command_buffer/service/program_cache_unittest.cc",
diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc
index ae7705b..d994024 100644
--- a/gpu/command_buffer/service/feature_info.cc
+++ b/gpu/command_buffer/service/feature_info.cc
@@ -1562,6 +1562,10 @@
       AddExtensionString("GL_WEBGL_multi_draw_instanced");
     }
   }
+
+  if (gfx::HasExtension(extensions, "GL_NV_internalformat_sample_query")) {
+    feature_flags_.nv_internalformat_sample_query = true;
+  }
 }
 
 void FeatureInfo::InitializeFloatAndHalfFloatFeatures(
diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h
index 922eb92..2435708 100644
--- a/gpu/command_buffer/service/feature_info.h
+++ b/gpu/command_buffer/service/feature_info.h
@@ -143,6 +143,7 @@
     bool khr_robust_buffer_access_behavior = false;
     bool webgl_multi_draw = false;
     bool webgl_multi_draw_instanced = false;
+    bool nv_internalformat_sample_query = false;
   };
 
   FeatureInfo();
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 319fe90..cd22fa43 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -835,6 +835,7 @@
   bool InitializeShaderTranslator();
   void DestroyShaderTranslator();
 
+  GLint ComputeMaxSamples();
   void UpdateCapabilities();
 
   // Helpers for the glGen and glDelete functions.
@@ -1937,6 +1938,11 @@
   // Wrapper for glFenceSync.
   GLsync DoFenceSync(GLenum condition, GLbitfield flags);
 
+  GLsizei InternalFormatSampleCountsHelper(
+      GLenum target,
+      GLenum format,
+      std::vector<GLint>* out_sample_counts);
+
   // Common validation for multisample extensions.
   bool ValidateRenderbufferStorageMultisample(GLsizei samples,
                                               GLenum internalformat,
@@ -4157,7 +4163,7 @@
   if (feature_info_->feature_flags().multisampled_render_to_texture ||
       feature_info_->feature_flags().chromium_framebuffer_multisample ||
       feature_info_->IsWebGL2OrES3Context()) {
-    DoGetIntegerv(GL_MAX_SAMPLES, &caps.max_samples, 1);
+    caps.max_samples = ComputeMaxSamples();
   }
 
   caps.num_stencil_bits = num_stencil_bits_;
@@ -4274,6 +4280,40 @@
   return caps;
 }
 
+GLint GLES2DecoderImpl::ComputeMaxSamples() {
+  GLint max_samples = 0;
+  DoGetIntegerv(GL_MAX_SAMPLES, &max_samples, 1);
+
+  if (feature_info_->IsWebGLContext() &&
+      feature_info_->feature_flags().nv_internalformat_sample_query) {
+    std::vector<GLint> temp;
+
+    auto minWithSamplesForFormat = [&](GLenum internalformat) {
+      temp.clear();
+      InternalFormatSampleCountsHelper(GL_RENDERBUFFER, internalformat, &temp);
+      max_samples = std::min(max_samples, temp[0]);
+    };
+
+    // OpenGL ES 3.0.5, section 4.4.2.2: "Implementations must support creation
+    // of renderbuffers in these required formats with up to the value of
+    // MAX_SAMPLES multisamples, with the exception of signed and unsigned
+    // integer formats."
+
+    // OpenGL ES 3.0.5, section 3.8.3.1
+    minWithSamplesForFormat(GL_RGBA8);
+    minWithSamplesForFormat(GL_SRGB8_ALPHA8);
+    minWithSamplesForFormat(GL_RGB10_A2);
+    minWithSamplesForFormat(GL_RGBA4);
+    minWithSamplesForFormat(GL_RGB5_A1);
+    minWithSamplesForFormat(GL_RGB8);
+    minWithSamplesForFormat(GL_RGB565);
+    minWithSamplesForFormat(GL_RG8);
+    minWithSamplesForFormat(GL_R8);
+  }
+
+  return max_samples;
+}
+
 void GLES2DecoderImpl::UpdateCapabilities() {
   util_.set_num_compressed_texture_formats(
       validators_->compressed_texture_format.GetValues().size());
@@ -18659,6 +18699,80 @@
   return api()->glFenceSyncFn(condition, flags);
 }
 
+GLsizei GLES2DecoderImpl::InternalFormatSampleCountsHelper(
+    GLenum target,
+    GLenum internalformat,
+    std::vector<GLint>* out_sample_counts) {
+  DCHECK(out_sample_counts == nullptr || out_sample_counts->size() == 0);
+
+  GLint num_sample_counts = 0;
+  if (gl_version_info().IsLowerThanGL(4, 2)) {
+    // No multisampling for integer formats.
+    if (GLES2Util::IsIntegerFormat(internalformat)) {
+      return 0;
+    }
+
+    GLint max_samples = renderbuffer_manager()->max_samples();
+    num_sample_counts = max_samples;
+
+    if (out_sample_counts != nullptr) {
+      out_sample_counts->reserve(num_sample_counts);
+      for (GLint sample_count = max_samples; sample_count > 0; --sample_count) {
+        out_sample_counts->push_back(sample_count);
+      }
+    }
+  } else {
+    api()->glGetInternalformativFn(target, internalformat, GL_NUM_SAMPLE_COUNTS,
+                                   1, &num_sample_counts);
+
+    bool remove_nonconformant_sample_counts =
+        feature_info_->IsWebGLContext() &&
+        feature_info_->feature_flags().nv_internalformat_sample_query;
+
+    if (out_sample_counts != nullptr || remove_nonconformant_sample_counts) {
+      std::vector<GLint> sample_counts(num_sample_counts);
+      api()->glGetInternalformativFn(target, internalformat, GL_SAMPLES,
+                                     num_sample_counts, sample_counts.data());
+
+      if (remove_nonconformant_sample_counts) {
+        ScopedGLErrorSuppressor suppressor(
+            "GLES2DecoderImpl::InternalFormatSampleCountsHelper",
+            error_state_.get());
+
+        auto is_nonconformant = [this, target,
+                                 internalformat](GLint sample_count) {
+          GLint conformant = GL_FALSE;
+          api()->glGetInternalformatSampleivNVFn(target, internalformat,
+                                                 sample_count, GL_CONFORMANT_NV,
+                                                 1, &conformant);
+
+          // getInternalformatSampleivNV does not work for all formats on NVIDIA
+          // Shield TV drivers. Assume that formats with large sample counts are
+          // non-conformant in case the query generates an error.
+          if (api()->glGetErrorFn() != GL_NO_ERROR) {
+            return sample_count > 8;
+          }
+          return conformant == GL_FALSE;
+        };
+
+        sample_counts.erase(
+            std::remove_if(sample_counts.begin(), sample_counts.end(),
+                           is_nonconformant),
+            sample_counts.end());
+        num_sample_counts = sample_counts.size();
+      }
+
+      if (out_sample_counts != nullptr) {
+        *out_sample_counts = std::move(sample_counts);
+      }
+    }
+  }
+
+  DCHECK(out_sample_counts == nullptr ||
+         out_sample_counts->size() == static_cast<size_t>(num_sample_counts));
+  return num_sample_counts;
+}
+
 error::Error GLES2DecoderImpl::HandleGetInternalformativ(
     uint32_t immediate_data_size,
     const volatile void* cmd_data) {
@@ -18684,52 +18798,37 @@
   }
 
   typedef cmds::GetInternalformativ::Result Result;
+
+  GLsizei num_sample_counts = 0;
+  std::vector<GLint> sample_counts;
+
   GLsizei num_values = 0;
-  std::vector<GLint> samples;
-  if (gl_version_info().IsLowerThanGL(4, 2)) {
-    if (!GLES2Util::IsIntegerFormat(format)) {
-      // No multisampling for integer formats.
-      GLint max_samples = renderbuffer_manager()->max_samples();
-      while (max_samples > 0) {
-        samples.push_back(max_samples);
-        --max_samples;
-      }
-    }
-    switch (pname) {
-      case GL_NUM_SAMPLE_COUNTS:
-        num_values = 1;
-        break;
-      case GL_SAMPLES:
-        num_values = static_cast<GLsizei>(samples.size());
-        break;
-      default:
-        NOTREACHED();
-        break;
-    }
-  } else {
-    switch (pname) {
-      case GL_NUM_SAMPLE_COUNTS:
-        num_values = 1;
-        break;
-      case GL_SAMPLES:
-        {
-          GLint value = 0;
-          api()->glGetInternalformativFn(target, format, GL_NUM_SAMPLE_COUNTS,
-                                         1, &value);
-          num_values = static_cast<GLsizei>(value);
-        }
-        break;
-      default:
-        NOTREACHED();
-        break;
-    }
+  GLint* values = nullptr;
+  switch (pname) {
+    case GL_NUM_SAMPLE_COUNTS:
+      num_sample_counts =
+          InternalFormatSampleCountsHelper(target, format, nullptr);
+      num_values = 1;
+      values = &num_sample_counts;
+      break;
+    case GL_SAMPLES:
+      num_sample_counts =
+          InternalFormatSampleCountsHelper(target, format, &sample_counts);
+      num_values = num_sample_counts;
+      values = sample_counts.data();
+      break;
+    default:
+      NOTREACHED();
+      break;
   }
+
   uint32_t checked_size = 0;
   if (!Result::ComputeSize(num_values).AssignIfValid(&checked_size)) {
     return error::kOutOfBounds;
   }
   Result* result = GetSharedMemoryAs<Result*>(
       c.params_shm_id, c.params_shm_offset, checked_size);
+
   GLint* params = result ? result->GetData() : nullptr;
   if (params == nullptr) {
     return error::kOutOfBounds;
@@ -18738,23 +18837,8 @@
   if (result->size != 0) {
     return error::kInvalidArguments;
   }
-  if (gl_version_info().IsLowerThanGL(4, 2)) {
-    switch (pname) {
-      case GL_NUM_SAMPLE_COUNTS:
-        params[0] = static_cast<GLint>(samples.size());
-        break;
-      case GL_SAMPLES:
-        for (size_t ii = 0; ii < samples.size(); ++ii) {
-          params[ii] = samples[ii];
-        }
-        break;
-      default:
-        NOTREACHED();
-        break;
-    }
-  } else {
-    api()->glGetInternalformativFn(target, format, pname, num_values, params);
-  }
+
+  std::copy(values, &values[num_values], params);
   result->SetNumResults(num_values);
   return error::kNoError;
 }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 743cc64..af6398c 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -466,9 +466,8 @@
                                         GL_NUM_SAMPLE_COUNTS, 1, _))
       .WillOnce(SetArgPointee<4>(kNumSampleCounts))
       .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8,
-                                        GL_SAMPLES, kNumSampleCounts,
-                                        result->GetData()))
+  EXPECT_CALL(*gl_, GetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_SAMPLES,
+                                        kNumSampleCounts, _))
       .Times(1)
       .RetiresOnSaturation();
   result->size = 0;
diff --git a/gpu/command_buffer/service/multi_draw_manager.cc b/gpu/command_buffer/service/multi_draw_manager.cc
index 6000fa9..498ed6ad 100644
--- a/gpu/command_buffer/service/multi_draw_manager.cc
+++ b/gpu/command_buffer/service/multi_draw_manager.cc
@@ -12,8 +12,8 @@
 namespace gpu {
 namespace gles2 {
 
-MultiDrawManager::ResultData::ResultData() = default;
-MultiDrawManager::ResultData::~ResultData() = default;
+MultiDrawManager::ResultData::ResultData()
+    : draw_function(DrawFunction::None) {}
 
 MultiDrawManager::ResultData::ResultData(ResultData&& rhs)
     : draw_function(rhs.draw_function),
@@ -25,6 +25,7 @@
       offsets(std::move(rhs.offsets)),
       indices(std::move(rhs.indices)),
       instance_counts(std::move(rhs.instance_counts)) {
+  rhs.draw_function = DrawFunction::None;
 }
 
 MultiDrawManager::ResultData& MultiDrawManager::ResultData::operator=(
@@ -41,32 +42,33 @@
   std::swap(offsets, rhs.offsets);
   std::swap(indices, rhs.indices);
   std::swap(instance_counts, rhs.instance_counts);
+
+  rhs.draw_function = DrawFunction::None;
   return *this;
 }
 
+MultiDrawManager::ResultData::~ResultData() {}
+
 MultiDrawManager::MultiDrawManager(IndexStorageType index_type)
-    : draw_state_(DrawState::End),
-      current_draw_offset_(0),
-      index_type_(index_type),
-      result_() {}
+    : current_draw_offset_(0), index_type_(index_type), result_() {}
 
 bool MultiDrawManager::Begin(GLsizei drawcount) {
-  if (draw_state_ != DrawState::End) {
-    return false;
-  }
   result_.drawcount = drawcount;
   current_draw_offset_ = 0;
-  draw_state_ = DrawState::Begin;
+  if (result_.draw_function != DrawFunction::None) {
+    NOTREACHED();
+    return false;
+  }
   return true;
 }
 
 bool MultiDrawManager::End(ResultData* result) {
   DCHECK(result);
-  if (draw_state_ != DrawState::Draw ||
+
+  if (result_.draw_function == DrawFunction::None ||
       current_draw_offset_ != result_.drawcount) {
     return false;
   }
-  draw_state_ = DrawState::End;
   *result = std::move(result_);
   return true;
 }
@@ -75,7 +77,10 @@
                                        const GLint* firsts,
                                        const GLsizei* counts,
                                        GLsizei drawcount) {
-  if (!EnsureDrawArraysFunction(DrawFunction::DrawArrays, mode, drawcount)) {
+  if (!EnsureDrawArraysFunction(DrawFunction::DrawArrays, mode) ||
+      base::CheckAdd(current_draw_offset_, drawcount).ValueOrDie() >
+          result_.drawcount) {
+    NOTREACHED();
     return false;
   }
   std::copy(firsts, firsts + drawcount, &result_.firsts[current_draw_offset_]);
@@ -89,8 +94,10 @@
                                                 const GLsizei* counts,
                                                 const GLsizei* instance_counts,
                                                 GLsizei drawcount) {
-  if (!EnsureDrawArraysFunction(DrawFunction::DrawArraysInstanced, mode,
-                                drawcount)) {
+  if (!EnsureDrawArraysFunction(DrawFunction::DrawArraysInstanced, mode) ||
+      base::CheckAdd(current_draw_offset_, drawcount).ValueOrDie() >
+          result_.drawcount) {
+    NOTREACHED();
     return false;
   }
   std::copy(firsts, firsts + drawcount, &result_.firsts[current_draw_offset_]);
@@ -106,8 +113,10 @@
                                          GLenum type,
                                          const GLsizei* offsets,
                                          GLsizei drawcount) {
-  if (!EnsureDrawElementsFunction(DrawFunction::DrawElements, mode, type,
-                                  drawcount)) {
+  if (!EnsureDrawElementsFunction(DrawFunction::DrawElements, mode, type) ||
+      base::CheckAdd(current_draw_offset_, drawcount).ValueOrDie() >
+          result_.drawcount) {
+    NOTREACHED();
     return false;
   }
   std::copy(counts, counts + drawcount, &result_.counts[current_draw_offset_]);
@@ -136,7 +145,10 @@
     const GLsizei* instance_counts,
     GLsizei drawcount) {
   if (!EnsureDrawElementsFunction(DrawFunction::DrawElementsInstanced, mode,
-                                  type, drawcount)) {
+                                  type) ||
+      base::CheckAdd(current_draw_offset_, drawcount).ValueOrDie() >
+          result_.drawcount) {
+    NOTREACHED();
     return false;
   }
   std::copy(counts, counts + drawcount, &result_.counts[current_draw_offset_]);
@@ -187,65 +199,30 @@
   }
 }
 
-bool MultiDrawManager::ValidateDrawcount(GLsizei drawcount) const {
-  if (drawcount < 0) {
-    return false;
-  }
-  GLsizei new_offset;
-  if (!base::CheckAdd(current_draw_offset_, drawcount)
-           .AssignIfValid(&new_offset)) {
-    return false;
-  }
-  if (new_offset > result_.drawcount) {
-    return false;
-  }
-  return true;
-}
-
 bool MultiDrawManager::EnsureDrawArraysFunction(DrawFunction draw_function,
-                                                GLenum mode,
-                                                GLsizei drawcount) {
-  if (!ValidateDrawcount(drawcount)) {
-    return false;
-  }
-  bool invalid_draw_state = draw_state_ == DrawState::End;
-  bool first_call = draw_state_ == DrawState::Begin;
+                                                GLenum mode) {
+  bool first_call = result_.draw_function == DrawFunction::None;
   bool enums_match = result_.mode == mode;
-
-  if (invalid_draw_state || (!first_call && !enums_match)) {
-    return false;
-  }
   if (first_call) {
-    draw_state_ = DrawState::Draw;
     result_.draw_function = draw_function;
     result_.mode = mode;
     ResizeArrays();
   }
-  return true;
+  return first_call || enums_match;
 }
 
 bool MultiDrawManager::EnsureDrawElementsFunction(DrawFunction draw_function,
                                                   GLenum mode,
-                                                  GLenum type,
-                                                  GLsizei drawcount) {
-  if (!ValidateDrawcount(drawcount)) {
-    return false;
-  }
-  bool invalid_draw_state = draw_state_ == DrawState::End;
-  bool first_call = draw_state_ == DrawState::Begin;
+                                                  GLenum type) {
+  bool first_call = result_.draw_function == DrawFunction::None;
   bool enums_match = result_.mode == mode && result_.type == type;
-
-  if (invalid_draw_state || (!first_call && !enums_match)) {
-    return false;
-  }
   if (first_call) {
-    draw_state_ = DrawState::Draw;
     result_.draw_function = draw_function;
     result_.mode = mode;
     result_.type = type;
     ResizeArrays();
   }
-  return true;
+  return first_call || enums_match;
 }
 
 }  // namespace gles2
diff --git a/gpu/command_buffer/service/multi_draw_manager.h b/gpu/command_buffer/service/multi_draw_manager.h
index 49dfbf9..daa42d9 100644
--- a/gpu/command_buffer/service/multi_draw_manager.h
+++ b/gpu/command_buffer/service/multi_draw_manager.h
@@ -20,13 +20,14 @@
 class GPU_GLES2_EXPORT MultiDrawManager {
  public:
   enum class DrawFunction {
+    None,
     DrawArrays,
     DrawArraysInstanced,
     DrawElements,
     DrawElementsInstanced,
   };
 
-  struct GPU_GLES2_EXPORT ResultData {
+  struct ResultData {
     DrawFunction draw_function;
     GLsizei drawcount;
     GLenum mode;
@@ -38,9 +39,9 @@
     std::vector<GLsizei> instance_counts;
 
     ResultData();
-    ~ResultData();
     ResultData(ResultData&& rhs);
     ResultData& operator=(ResultData&& rhs);
+    ~ResultData();
   };
 
   enum class IndexStorageType {
@@ -75,22 +76,11 @@
 
  private:
   void ResizeArrays();
-  bool ValidateDrawcount(GLsizei drawcount) const;
-  bool EnsureDrawArraysFunction(DrawFunction draw_function,
-                                GLenum mode,
-                                GLsizei drawcount);
+  bool EnsureDrawArraysFunction(DrawFunction draw_function, GLenum mode);
   bool EnsureDrawElementsFunction(DrawFunction draw_function,
                                   GLenum mode,
-                                  GLenum type,
-                                  GLsizei drawcount);
+                                  GLenum type);
 
-  enum class DrawState {
-    Begin,
-    Draw,
-    End,
-  };
-
-  DrawState draw_state_;
   GLsizei current_draw_offset_;
   IndexStorageType index_type_;
   ResultData result_;
diff --git a/gpu/command_buffer/service/multi_draw_manager_unittest.cc b/gpu/command_buffer/service/multi_draw_manager_unittest.cc
deleted file mode 100644
index 65adf52..0000000
--- a/gpu/command_buffer/service/multi_draw_manager_unittest.cc
+++ /dev/null
@@ -1,232 +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 "gpu/command_buffer/service/multi_draw_manager.h"
-
-#include <memory>
-#include <tuple>
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "ui/gl/gl_bindings.h"
-
-namespace gpu {
-namespace gles2 {
-
-namespace {
-
-using Param = std::tuple<MultiDrawManager::IndexStorageType,
-                         MultiDrawManager::DrawFunction>;
-
-}  // namespace
-
-class MultiDrawManagerTest : public testing::TestWithParam<Param> {
- public:
-  MultiDrawManagerTest()
-      : multi_draw_manager_(new MultiDrawManager(std::get<0>(GetParam()))) {}
-
- protected:
-  bool DoMultiDraw(uint32_t count,
-                   GLenum mode = GL_TRIANGLES,
-                   GLenum type = GL_UNSIGNED_INT) {
-    std::vector<GLsizei> data(count);
-    switch (std::get<1>(GetParam())) {
-      case MultiDrawManager::DrawFunction::DrawArrays:
-        return multi_draw_manager_->MultiDrawArrays(mode, data.data(),
-                                                    data.data(), count);
-
-      case MultiDrawManager::DrawFunction::DrawArraysInstanced:
-        return multi_draw_manager_->MultiDrawArraysInstanced(
-            mode, data.data(), data.data(), data.data(), count);
-
-      case MultiDrawManager::DrawFunction::DrawElements:
-        return multi_draw_manager_->MultiDrawElements(mode, data.data(), type,
-                                                      data.data(), count);
-
-      case MultiDrawManager::DrawFunction::DrawElementsInstanced:
-        return multi_draw_manager_->MultiDrawElementsInstanced(
-            mode, data.data(), type, data.data(), data.data(), count);
-    }
-  }
-
-  void CheckResultSize(uint32_t count,
-                       const MultiDrawManager::ResultData& result) {
-    MultiDrawManager::DrawFunction draw_function = std::get<1>(GetParam());
-    EXPECT_TRUE(draw_function == result.draw_function);
-
-    switch (draw_function) {
-      case MultiDrawManager::DrawFunction::DrawArraysInstanced:
-        EXPECT_TRUE(result.instance_counts.size() == count);
-        FALLTHROUGH;
-      case MultiDrawManager::DrawFunction::DrawArrays:
-        EXPECT_TRUE(result.firsts.size() == count);
-        EXPECT_TRUE(result.counts.size() == count);
-        break;
-      case MultiDrawManager::DrawFunction::DrawElementsInstanced:
-        EXPECT_TRUE(result.instance_counts.size() == count);
-        FALLTHROUGH;
-      case MultiDrawManager::DrawFunction::DrawElements:
-        EXPECT_TRUE(result.counts.size() == count);
-        switch (std::get<0>(GetParam())) {
-          case MultiDrawManager::IndexStorageType::Offset:
-            EXPECT_TRUE(result.offsets.size() == count);
-            break;
-          case MultiDrawManager::IndexStorageType::Pointer:
-            EXPECT_TRUE(result.indices.size() == count);
-            break;
-        }
-        break;
-    }
-  }
-
-  std::unique_ptr<MultiDrawManager> multi_draw_manager_;
-};
-
-// Test that the simple case succeeds
-TEST_P(MultiDrawManagerTest, Success) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(100));
-  EXPECT_TRUE(multi_draw_manager_->End(&result));
-  CheckResultSize(100, result);
-}
-
-// Test that the internal state of the multi draw manager resets such that
-// successive valid multi draws can be executed
-TEST_P(MultiDrawManagerTest, SuccessAfterSuccess) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(100));
-  EXPECT_TRUE(multi_draw_manager_->End(&result));
-  CheckResultSize(100, result);
-
-  EXPECT_TRUE(multi_draw_manager_->Begin(1000));
-  EXPECT_TRUE(DoMultiDraw(1000));
-  EXPECT_TRUE(multi_draw_manager_->End(&result));
-  CheckResultSize(1000, result);
-}
-
-// Test that multiple chunked multi draw calls succeed
-TEST_P(MultiDrawManagerTest, SuccessMultiple) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(83));
-  EXPECT_TRUE(DoMultiDraw(4));
-  EXPECT_TRUE(DoMultiDraw(13));
-  EXPECT_TRUE(multi_draw_manager_->End(&result));
-  CheckResultSize(100, result);
-}
-
-// Test that it is invalid to submit an empty multi draw
-TEST_P(MultiDrawManagerTest, Empty) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(0));
-  EXPECT_FALSE(multi_draw_manager_->End(&result));
-}
-
-// Test that it is invalid to end a multi draw if it has not been started
-TEST_P(MultiDrawManagerTest, EndBeforeBegin) {
-  MultiDrawManager::ResultData result;
-  EXPECT_FALSE(multi_draw_manager_->End(&result));
-}
-
-// Test that it is invalid to begin a multi draw twice
-TEST_P(MultiDrawManagerTest, BeginAfterBegin) {
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_FALSE(multi_draw_manager_->Begin(100));
-}
-
-// Test that it is invalid to begin a multi draw twice, even if
-// the first begin was empty
-TEST_P(MultiDrawManagerTest, BeginAfterEmptyBegin) {
-  EXPECT_TRUE(multi_draw_manager_->Begin(0));
-  EXPECT_FALSE(multi_draw_manager_->Begin(100));
-}
-
-// Test that it is invalid to do a multi draw before begin
-TEST_P(MultiDrawManagerTest, DrawBeforeBegin) {
-  EXPECT_FALSE(DoMultiDraw(1));
-}
-
-// Test that it is invalid to end a multi draw twice
-TEST_P(MultiDrawManagerTest, DoubleEnd) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(1));
-  EXPECT_TRUE(DoMultiDraw(1));
-  EXPECT_TRUE(multi_draw_manager_->End(&result));
-  EXPECT_FALSE(multi_draw_manager_->End(&result));
-}
-
-// Test that it is invalid to end a multi draw before the drawcount
-// is saturated
-TEST_P(MultiDrawManagerTest, Underflow) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(99));
-  EXPECT_FALSE(multi_draw_manager_->End(&result));
-}
-
-// Test that it is invalid to end a multi draw before the drawcount
-// is saturated, using multiple chunks
-TEST_P(MultiDrawManagerTest, UnderflowMultiple) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(42));
-  EXPECT_TRUE(DoMultiDraw(31));
-  EXPECT_TRUE(DoMultiDraw(26));
-  EXPECT_FALSE(multi_draw_manager_->End(&result));
-}
-
-// Test that it is invalid to do a multi draw that overflows the drawcount
-TEST_P(MultiDrawManagerTest, Overflow) {
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_FALSE(DoMultiDraw(101));
-}
-
-// Test that it is invalid to do a multi draw that overflows the drawcount,
-// using multiple chunks
-TEST_P(MultiDrawManagerTest, OverflowMultiple) {
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(31));
-  EXPECT_TRUE(DoMultiDraw(49));
-  EXPECT_FALSE(DoMultiDraw(21));
-}
-
-// Test that it is invalid to do a multi draw that does not match the first
-// chunk's draw mode
-TEST_P(MultiDrawManagerTest, DrawModeMismatch) {
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(50, GL_TRIANGLES));
-  EXPECT_FALSE(DoMultiDraw(50, GL_LINES));
-}
-
-// Test that it is invalid to do a multi draw that does not match the first
-// chunk's element type
-TEST_P(MultiDrawManagerTest, ElementTypeMismatch) {
-  MultiDrawManager::DrawFunction draw_function = std::get<1>(GetParam());
-  if (draw_function != MultiDrawManager::DrawFunction::DrawElements &&
-      draw_function != MultiDrawManager::DrawFunction::DrawElementsInstanced) {
-    return;
-  }
-
-  MultiDrawManager::ResultData result;
-  EXPECT_TRUE(multi_draw_manager_->Begin(100));
-  EXPECT_TRUE(DoMultiDraw(50, GL_TRIANGLES, GL_UNSIGNED_INT));
-  EXPECT_FALSE(DoMultiDraw(50, GL_TRIANGLES, GL_UNSIGNED_SHORT));
-}
-
-INSTANTIATE_TEST_CASE_P(
-    ,
-    MultiDrawManagerTest,
-    testing::Combine(
-        testing::Values(MultiDrawManager::IndexStorageType::Offset,
-                        MultiDrawManager::IndexStorageType::Pointer),
-        testing::Values(
-            MultiDrawManager::DrawFunction::DrawArrays,
-            MultiDrawManager::DrawFunction::DrawArraysInstanced,
-            MultiDrawManager::DrawFunction::DrawElements,
-            MultiDrawManager::DrawFunction::DrawElementsInstanced)));
-
-}  // namespace gles2
-}  // namespace gpu
diff --git a/gpu/ipc/service/gpu_channel.cc b/gpu/ipc/service/gpu_channel.cc
index 16e539de..8868883 100644
--- a/gpu/ipc/service/gpu_channel.cc
+++ b/gpu/ipc/service/gpu_channel.cc
@@ -127,6 +127,8 @@
   scoped_refptr<ImageDecodeAcceleratorStub> image_decode_accelerator_stub_;
   base::ThreadChecker io_thread_checker_;
 
+  bool allow_crash_for_testing_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(GpuChannelMessageFilter);
 };
 
@@ -145,6 +147,9 @@
               static_cast<int32_t>(
                   GpuChannelReservedRoutes::kImageDecodeAccelerator))) {
   io_thread_checker_.DetachFromThread();
+  allow_crash_for_testing_ = gpu_channel->gpu_channel_manager()
+                                 ->gpu_preferences()
+                                 .enable_gpu_benchmarking_extension;
 }
 
 GpuChannelMessageFilter::~GpuChannelMessageFilter() {
@@ -240,6 +245,18 @@
     case GpuChannelMsg_CreateSharedImage::ID:
     case GpuChannelMsg_DestroySharedImage::ID:
       return MessageErrorHandler(message, "Invalid message");
+    case GpuChannelMsg_CrashForTesting::ID:
+      // Handle this message early, on the IO thread, in case the main
+      // thread is hung. This is the purpose of this message: generating
+      // minidumps on the bots, which are symbolized later by the test
+      // harness. Only pay attention to this message if Telemetry's GPU
+      // benchmarking extension was enabled via the command line, which
+      // exposes privileged APIs to JavaScript.
+      if (allow_crash_for_testing_) {
+        gl::Crash();
+      }
+      // Won't be reached if the extension is enabled.
+      return MessageErrorHandler(message, "Crashes for testing are disabled");
     default:
       break;
   }
@@ -510,7 +527,6 @@
                         OnCreateCommandBuffer)
     IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer,
                         OnDestroyCommandBuffer)
-    IPC_MESSAGE_HANDLER(GpuChannelMsg_CrashForTesting, OnCrashForTesting)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
@@ -709,16 +725,6 @@
   RemoveRoute(route_id);
 }
 
-void GpuChannel::OnCrashForTesting() {
-  // Only pay attention to this message if Telemetry's GPU
-  // benchmarking extension was enabled via the command line, which
-  // exposes privileged APIs to JavaScript.
-  if (!gpu_channel_manager_->gpu_preferences()
-           .enable_gpu_benchmarking_extension)
-    return;
-  gl::Crash();
-}
-
 void GpuChannel::CacheShader(const std::string& key,
                              const std::string& shader) {
   gpu_channel_manager_->delegate()->StoreShaderToDisk(client_id_, key, shader);
diff --git a/gpu/ipc/service/gpu_channel.h b/gpu/ipc/service/gpu_channel.h
index 2937600..77d23d0 100644
--- a/gpu/ipc/service/gpu_channel.h
+++ b/gpu/ipc/service/gpu_channel.h
@@ -169,7 +169,6 @@
                              gpu::ContextResult* result,
                              gpu::Capabilities* capabilities);
   void OnDestroyCommandBuffer(int32_t route_id);
-  void OnCrashForTesting();
 
   std::unique_ptr<IPC::SyncChannel> sync_channel_;  // nullptr in tests.
   IPC::Sender* channel_;  // Same as sync_channel_.get() except in tests.
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 5440be35..e27f6a5 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -248,6 +248,8 @@
 
   # These are relative to $target_gen_dir.
   outputs = [
+    "lib/browser/protocol/base_string_adapter.cc",
+    "lib/browser/protocol/base_string_adapter.h",
     "lib/browser/protocol/dp_browser.cc",
     "lib/browser/protocol/dp_browser.h",
     "lib/browser/protocol/dp_headless_experimental.cc",
@@ -305,8 +307,6 @@
     "lib/browser/protocol/headless_handler.h",
     "lib/browser/protocol/page_handler.cc",
     "lib/browser/protocol/page_handler.h",
-    "lib/browser/protocol/protocol_string.cc",
-    "lib/browser/protocol/protocol_string.h",
     "lib/browser/protocol/target_handler.cc",
     "lib/browser/protocol/target_handler.h",
     "lib/headless_content_client.cc",
@@ -425,7 +425,7 @@
     deps += [
       "//components/crash/core/common:crash_key",
       "//components/security_state/content",
-      "//components/services/pdf_compositor:pdf_compositor_manifest",
+      "//components/services/pdf_compositor/public/cpp:manifest",
       "//components/services/pdf_compositor/public/interfaces",
       "//gin",
       "//third_party/blink/public:blink",
@@ -552,7 +552,6 @@
 
 test("headless_unittests") {
   sources = [
-    "lib/browser/protocol/protocol_unittest.cc",
     "public/domains/types_unittest.cc",
     "public/util/error_reporter_unittest.cc",
   ]
@@ -573,7 +572,7 @@
     "//base/test:run_all_unittests",
     "//base/test:test_support",
     "//components/security_state/content",
-    "//components/services/pdf_compositor:pdf_compositor_manifest",
+    "//components/services/pdf_compositor/public/cpp:manifest",
     "//components/services/pdf_compositor/public/interfaces",
     "//content/public/app:both",
     "//content/public/child:child",
@@ -733,7 +732,7 @@
     ":headless_renderer",
     "//base",
     "//components/security_state/content",
-    "//components/services/pdf_compositor:pdf_compositor_manifest",
+    "//components/services/pdf_compositor/public/cpp:manifest",
     "//components/services/pdf_compositor/public/interfaces",
     "//content/test:test_support",
     "//services/network/public/mojom",
@@ -786,7 +785,7 @@
     ]
     deps = [
       ":headless",
-      "//components/services/pdf_compositor:pdf_compositor_manifest",
+      "//components/services/pdf_compositor/public/cpp:manifest",
       "//components/services/pdf_compositor/public/interfaces",
       "//content:sandbox_helper_win",
       "//content/public/browser",
@@ -870,7 +869,7 @@
     ":headless_renderer",
     "//components/os_crypt",
     "//components/security_state/content",
-    "//components/services/pdf_compositor:pdf_compositor_manifest",
+    "//components/services/pdf_compositor/public/cpp:manifest",
     "//components/services/pdf_compositor/public/interfaces",
     "//content/public/app:both",
     "//content/public/browser",
diff --git a/headless/lib/browser/DEPS b/headless/lib/browser/DEPS
index f60aeeb..ff46d42 100644
--- a/headless/lib/browser/DEPS
+++ b/headless/lib/browser/DEPS
@@ -3,7 +3,7 @@
   "+components/printing/browser",
   "+components/printing/common",
   "+components/security_state",
-  "+components/services/pdf_compositor/pdf_compositor_manifest.h",
+  "+components/services/pdf_compositor/public/cpp",
   "+components/viz",
   "+printing",
   "+services/network",
diff --git a/headless/lib/browser/devtools_api/domain_h.template b/headless/lib/browser/devtools_api/domain_h.template
index a113383..a070791d 100644
--- a/headless/lib/browser/devtools_api/domain_h.template
+++ b/headless/lib/browser/devtools_api/domain_h.template
@@ -10,7 +10,7 @@
 #include "base/callback.h"
 #include "base/observer_list.h"
 #include "base/values.h"
-#include "headless/lib/browser/protocol/protocol_string.h"
+#include "headless/lib/browser/protocol/base_string_adapter.h"
 {% for domain_name in domain.dependencies %}
 #include "headless/public/devtools/domains/types_{{domain_name | camelcase_to_hacker_style}}.h"
 {% endfor %}
diff --git a/headless/lib/browser/devtools_api/domain_types_h.template b/headless/lib/browser/devtools_api/domain_types_h.template
index 1ad4813..dd85de1 100644
--- a/headless/lib/browser/devtools_api/domain_types_h.template
+++ b/headless/lib/browser/devtools_api/domain_types_h.template
@@ -9,7 +9,7 @@
 
 #include "base/optional.h"
 #include "base/values.h"
-#include "headless/lib/browser/protocol/protocol_string.h"
+#include "headless/lib/browser/protocol/base_string_adapter.h"
 {% for domain_name in domain.dependencies %}
 #include "headless/public/devtools/internal/types_forward_declarations_{{domain_name | camelcase_to_hacker_style}}.h"
 {% endfor %}
diff --git a/headless/lib/browser/headless_devtools_manager_delegate.cc b/headless/lib/browser/headless_devtools_manager_delegate.cc
index bd611875..fa2f114 100644
--- a/headless/lib/browser/headless_devtools_manager_delegate.cc
+++ b/headless/lib/browser/headless_devtools_manager_delegate.cc
@@ -25,12 +25,11 @@
 void HeadlessDevToolsManagerDelegate::HandleCommand(
     content::DevToolsAgentHost* agent_host,
     content::DevToolsAgentHostClient* client,
-    std::unique_ptr<base::DictionaryValue> command,
+    const std::string& method,
     const std::string& message,
     NotHandledCallback callback) {
   DCHECK(sessions_.find(client) != sessions_.end());
-  sessions_[client]->HandleCommand(std::move(command), message,
-                                   std::move(callback));
+  sessions_[client]->HandleCommand(method, message, std::move(callback));
 }
 
 scoped_refptr<content::DevToolsAgentHost>
diff --git a/headless/lib/browser/headless_devtools_manager_delegate.h b/headless/lib/browser/headless_devtools_manager_delegate.h
index eb40d404..9a43363 100644
--- a/headless/lib/browser/headless_devtools_manager_delegate.h
+++ b/headless/lib/browser/headless_devtools_manager_delegate.h
@@ -31,7 +31,7 @@
   // DevToolsManagerDelegate implementation:
   void HandleCommand(content::DevToolsAgentHost* agent_host,
                      content::DevToolsAgentHostClient* client,
-                     std::unique_ptr<base::DictionaryValue> command,
+                     const std::string& method,
                      const std::string& message,
                      NotHandledCallback callback) override;
   scoped_refptr<content::DevToolsAgentHost> CreateNewTarget(
diff --git a/headless/lib/browser/headless_overlay_manifests.cc b/headless/lib/browser/headless_overlay_manifests.cc
index 7aed11d..d9320cabd 100644
--- a/headless/lib/browser/headless_overlay_manifests.cc
+++ b/headless/lib/browser/headless_overlay_manifests.cc
@@ -5,7 +5,7 @@
 #include "headless/lib/browser/headless_overlay_manifests.h"
 
 #include "base/no_destructor.h"
-#include "components/services/pdf_compositor/pdf_compositor_manifest.h"
+#include "components/services/pdf_compositor/public/cpp/manifest.h"
 #include "components/services/pdf_compositor/public/interfaces/pdf_compositor.mojom.h"
 #include "services/service_manager/public/cpp/manifest_builder.h"
 
@@ -24,7 +24,7 @@
 GetHeadlessContentPackagedServicesOverlayManifest() {
   static base::NoDestructor<service_manager::Manifest> manifest{
       service_manager::ManifestBuilder()
-          .PackageService(pdf_compositor::GetManifest())
+          .PackageService(printing::GetPdfCompositorManifest())
           .Build()};
 
   return *manifest;
diff --git a/headless/lib/browser/protocol/headless_devtools_session.cc b/headless/lib/browser/protocol/headless_devtools_session.cc
index 0c3e357..1fcf62a 100644
--- a/headless/lib/browser/protocol/headless_devtools_session.cc
+++ b/headless/lib/browser/protocol/headless_devtools_session.cc
@@ -42,28 +42,23 @@
 }
 
 void HeadlessDevToolsSession::HandleCommand(
-    std::unique_ptr<base::DictionaryValue> command,
+    const std::string& method,
     const std::string& message,
     content::DevToolsManagerDelegate::NotHandledCallback callback) {
-  if (!browser_) {
-    std::move(callback).Run(std::move(command), message);
+  if (!browser_ || !dispatcher_->canDispatch(method)) {
+    std::move(callback).Run(message);
     return;
   }
   int call_id;
-  std::string method;
-  std::unique_ptr<protocol::Value> protocolCommand =
-      protocol::toProtocolValue(command.get(), 1000);
-  if (!dispatcher_->parseCommand(protocolCommand.get(), &call_id, &method)) {
+  std::string unused;
+  std::unique_ptr<protocol::DictionaryValue> value =
+      protocol::DictionaryValue::cast(protocol::StringUtil::parseJSON(message));
+  if (!dispatcher_->parseCommand(value.get(), &call_id, &unused))
     return;
-  }
-  if (dispatcher_->canDispatch(method)) {
-    pending_commands_[call_id] =
-        std::make_pair(std::move(callback), std::move(command));
-    dispatcher_->dispatch(call_id, method, std::move(protocolCommand), message);
-    return;
-  }
-  std::move(callback).Run(std::move(command), message);
+  pending_commands_[call_id] = std::move(callback);
+  dispatcher_->dispatch(call_id, method, std::move(value), message);
 }
+
 void HeadlessDevToolsSession::AddHandler(
     std::unique_ptr<protocol::DomainHandler> handler) {
   handler->Wire(dispatcher_.get());
@@ -80,9 +75,9 @@
 void HeadlessDevToolsSession::fallThrough(int call_id,
                                           const std::string& method,
                                           const std::string& message) {
-  PendingCommand command = std::move(pending_commands_[call_id]);
+  auto callback = std::move(pending_commands_[call_id]);
   pending_commands_.erase(call_id);
-  std::move(command.first).Run(std::move(command.second), message);
+  std::move(callback).Run(message);
 }
 
 void HeadlessDevToolsSession::sendProtocolNotification(
diff --git a/headless/lib/browser/protocol/headless_devtools_session.h b/headless/lib/browser/protocol/headless_devtools_session.h
index 4a28551d1..f2daa96 100644
--- a/headless/lib/browser/protocol/headless_devtools_session.h
+++ b/headless/lib/browser/protocol/headless_devtools_session.h
@@ -35,7 +35,7 @@
   ~HeadlessDevToolsSession() override;
 
   void HandleCommand(
-      std::unique_ptr<base::DictionaryValue> command,
+      const std::string& method,
       const std::string& message,
       content::DevToolsManagerDelegate::NotHandledCallback callback);
 
@@ -58,10 +58,8 @@
   content::DevToolsAgentHostClient* const client_;
   std::unique_ptr<UberDispatcher> dispatcher_;
   base::flat_map<std::string, std::unique_ptr<DomainHandler>> handlers_;
-  using PendingCommand =
-      std::pair<content::DevToolsManagerDelegate::NotHandledCallback,
-                std::unique_ptr<base::DictionaryValue>>;
-  base::flat_map<int, PendingCommand> pending_commands_;
+  base::flat_map<int, content::DevToolsManagerDelegate::NotHandledCallback>
+      pending_commands_;
 
   DISALLOW_COPY_AND_ASSIGN(HeadlessDevToolsSession);
 };
diff --git a/headless/lib/browser/protocol/protocol_string.cc b/headless/lib/browser/protocol/protocol_string.cc
deleted file mode 100644
index b6b10854..0000000
--- a/headless/lib/browser/protocol/protocol_string.cc
+++ /dev/null
@@ -1,202 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "headless/lib/browser/protocol/protocol_string.h"
-
-#include <utility>
-#include "base/base64.h"
-#include "base/json/json_reader.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string16.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "headless/lib/browser/protocol/protocol.h"
-
-namespace headless {
-namespace protocol {
-
-std::unique_ptr<Value> toProtocolValue(const base::Value* value, int depth) {
-  if (!value || !depth)
-    return nullptr;
-  if (value->is_none())
-    return Value::null();
-  if (value->is_bool()) {
-    bool inner;
-    value->GetAsBoolean(&inner);
-    return FundamentalValue::create(inner);
-  }
-  if (value->is_int()) {
-    int inner;
-    value->GetAsInteger(&inner);
-    return FundamentalValue::create(inner);
-  }
-  if (value->is_double()) {
-    double inner;
-    value->GetAsDouble(&inner);
-    return FundamentalValue::create(inner);
-  }
-  if (value->is_string()) {
-    std::string inner;
-    value->GetAsString(&inner);
-    return StringValue::create(inner);
-  }
-  if (value->is_list()) {
-    const base::ListValue* list = nullptr;
-    value->GetAsList(&list);
-    std::unique_ptr<ListValue> result = ListValue::create();
-    for (size_t i = 0; i < list->GetSize(); i++) {
-      const base::Value* item = nullptr;
-      list->Get(i, &item);
-      std::unique_ptr<Value> converted = toProtocolValue(item, depth - 1);
-      if (converted)
-        result->pushValue(std::move(converted));
-    }
-    return std::move(result);
-  }
-  if (value->is_dict()) {
-    const base::DictionaryValue* dictionary = nullptr;
-    value->GetAsDictionary(&dictionary);
-    std::unique_ptr<DictionaryValue> result = DictionaryValue::create();
-    for (base::DictionaryValue::Iterator it(*dictionary); !it.IsAtEnd();
-         it.Advance()) {
-      std::unique_ptr<Value> converted =
-          toProtocolValue(&it.value(), depth - 1);
-      if (converted)
-        result->setValue(it.key(), std::move(converted));
-    }
-    return std::move(result);
-  }
-  return nullptr;
-}
-
-std::unique_ptr<base::Value> toBaseValue(Value* value, int depth) {
-  if (!value || !depth)
-    return nullptr;
-  if (value->type() == Value::TypeNull)
-    return std::make_unique<base::Value>();
-  if (value->type() == Value::TypeBoolean) {
-    bool inner;
-    value->asBoolean(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == Value::TypeInteger) {
-    int inner;
-    value->asInteger(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == Value::TypeDouble) {
-    double inner;
-    value->asDouble(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == Value::TypeString) {
-    std::string inner;
-    value->asString(&inner);
-    return base::WrapUnique(new base::Value(inner));
-  }
-  if (value->type() == Value::TypeArray) {
-    ListValue* list = ListValue::cast(value);
-    std::unique_ptr<base::ListValue> result(new base::ListValue());
-    for (size_t i = 0; i < list->size(); i++) {
-      std::unique_ptr<base::Value> converted =
-          toBaseValue(list->at(i), depth - 1);
-      if (converted)
-        result->Append(std::move(converted));
-    }
-    return std::move(result);
-  }
-  if (value->type() == Value::TypeObject) {
-    DictionaryValue* dict = DictionaryValue::cast(value);
-    std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
-    for (size_t i = 0; i < dict->size(); i++) {
-      DictionaryValue::Entry entry = dict->at(i);
-      std::unique_ptr<base::Value> converted =
-          toBaseValue(entry.second, depth - 1);
-      if (converted)
-        result->SetWithoutPathExpansion(entry.first, std::move(converted));
-    }
-    return std::move(result);
-  }
-  return nullptr;
-}
-
-// static
-std::unique_ptr<Value> StringUtil::parseJSON(const std::string& json) {
-  std::unique_ptr<base::Value> value = base::JSONReader::Read(json);
-  return toProtocolValue(value.get(), 1000);
-}
-
-StringBuilder::StringBuilder() {}
-
-StringBuilder::~StringBuilder() {}
-
-void StringBuilder::append(const std::string& s) {
-  string_ += s;
-}
-
-void StringBuilder::append(char c) {
-  string_ += c;
-}
-
-void StringBuilder::append(const char* characters, size_t length) {
-  string_.append(characters, length);
-}
-
-// static
-void StringUtil::builderAppendQuotedString(StringBuilder& builder,
-                                           const String& str) {
-  builder.append('"');
-  base::string16 str16 = base::UTF8ToUTF16(str);
-  escapeWideStringForJSON(reinterpret_cast<const uint16_t*>(&str16[0]),
-                          str16.length(), &builder);
-  builder.append('"');
-}
-
-std::string StringBuilder::toString() {
-  return string_;
-}
-
-void StringBuilder::reserveCapacity(size_t capacity) {
-  string_.reserve(capacity);
-}
-
-Binary::Binary() : bytes_(new base::RefCountedBytes) {}
-Binary::Binary(const Binary& binary) : bytes_(binary.bytes_) {}
-Binary::Binary(scoped_refptr<base::RefCountedMemory> bytes) : bytes_(bytes) {}
-Binary::~Binary() {}
-
-String Binary::toBase64() const {
-  std::string encoded;
-  base::Base64Encode(
-      base::StringPiece(reinterpret_cast<const char*>(data()), size()),
-      &encoded);
-  return encoded;
-}
-
-// static
-Binary Binary::fromBase64(const String& base64, bool* success) {
-  std::string decoded;
-  *success = base::Base64Decode(base::StringPiece(base64), &decoded);
-  if (*success) {
-    return Binary::fromString(std::move(decoded));
-  }
-  return Binary();
-}
-
-// static
-Binary Binary::fromRefCounted(scoped_refptr<base::RefCountedMemory> memory) {
-  return Binary(memory);
-}
-
-// static
-Binary Binary::fromVector(std::vector<uint8_t> data) {
-  return Binary(base::RefCountedBytes::TakeVector(&data));
-}
-
-// static
-Binary Binary::fromString(std::string data) {
-  return Binary(base::RefCountedString::TakeString(&data));
-}
-}  // namespace protocol
-}  // namespace headless
diff --git a/headless/lib/browser/protocol/protocol_unittest.cc b/headless/lib/browser/protocol/protocol_unittest.cc
deleted file mode 100644
index 3d5419f9..0000000
--- a/headless/lib/browser/protocol/protocol_unittest.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "headless/lib/browser/protocol/protocol_string.h"
-
-#include <vector>
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace headless {
-namespace protocol {
-namespace {
-TEST(ProtocolBinaryTest, base64EmptyArgs) {
-  EXPECT_EQ(protocol::String(), Binary().toBase64());
-
-  bool success = false;
-  Binary decoded = Binary::fromBase64("", &success);
-  EXPECT_TRUE(success);
-  EXPECT_EQ(
-      std::vector<uint8_t>(),
-      std::vector<uint8_t>(decoded.data(), decoded.data() + decoded.size()));
-}
-
-TEST(ProtocolStringTest, AllBytesBase64Roundtrip) {
-  std::vector<uint8_t> all_bytes;
-  for (int ii = 0; ii < 255; ++ii)
-    all_bytes.push_back(ii);
-  Binary binary = Binary::fromVector(all_bytes);
-  bool success = false;
-  Binary decoded = Binary::fromBase64(binary.toBase64(), &success);
-  EXPECT_TRUE(success);
-  std::vector<uint8_t> decoded_bytes(decoded.data(),
-                                     decoded.data() + decoded.size());
-  EXPECT_EQ(all_bytes, decoded_bytes);
-}
-
-TEST(ProtocolStringTest, HelloWorldBase64Roundtrip) {
-  const char* kMsg = "Hello, world.";
-  std::vector<uint8_t> msg(kMsg, kMsg + strlen(kMsg));
-  EXPECT_EQ(strlen(kMsg), msg.size());
-
-  protocol::String encoded = Binary::fromVector(msg).toBase64();
-  EXPECT_EQ("SGVsbG8sIHdvcmxkLg==", encoded);
-  bool success = false;
-  Binary decoded_binary = Binary::fromBase64(encoded, &success);
-  EXPECT_TRUE(success);
-  std::vector<uint8_t> decoded(decoded_binary.data(),
-                               decoded_binary.data() + decoded_binary.size());
-  EXPECT_EQ(msg, decoded);
-}
-
-TEST(ProtocolBinaryTest, InvalidBase64Decode) {
-  bool success = true;
-  Binary binary = Binary::fromBase64("This is not base64.", &success);
-  EXPECT_FALSE(success);
-}
-}  // namespace
-}  // namespace protocol
-}  // namespace headless
diff --git a/headless/protocol_config.json b/headless/protocol_config.json
index b2511d38..2a035a0 100644
--- a/headless/protocol_config.json
+++ b/headless/protocol_config.json
@@ -36,7 +36,7 @@
     "lib": {
         "package": "headless/lib/browser/protocol",
         "output": "lib/browser/protocol",
-        "string_header": "headless/lib/browser/protocol/protocol_string.h",
+        "string_header": "headless/lib/browser/protocol/base_string_adapter.h",
         "export_macro": "HEADLESS_EXPORT",
         "export_header": "headless/public/headless_export.h"
     }
diff --git a/headless/public/internal/value_conversions.h b/headless/public/internal/value_conversions.h
index 9f18f32..126d1ef 100644
--- a/headless/public/internal/value_conversions.h
+++ b/headless/public/internal/value_conversions.h
@@ -7,7 +7,7 @@
 
 #include <memory>
 
-#include "headless/lib/browser/protocol/protocol_string.h"
+#include "headless/lib/browser/protocol/base_string_adapter.h"
 #include "headless/public/util/error_reporter.h"
 
 namespace headless {
diff --git a/ios/build/bots/scripts/run.py b/ios/build/bots/scripts/run.py
index 3954f02..142b9946 100755
--- a/ios/build/bots/scripts/run.py
+++ b/ios/build/bots/scripts/run.py
@@ -19,6 +19,7 @@
 
 import argparse
 import json
+import logging
 import os
 import sys
 import traceback
@@ -28,6 +29,9 @@
 
 
 def main():
+  logging.basicConfig(format='[%(asctime)s:%(levelname)s] %(message)s',
+    level=logging.DEBUG, datefmt='%I:%M:%S')
+
   args, test_args = parse_args()
 
   summary = {}
diff --git a/ios/build/bots/scripts/test_runner.py b/ios/build/bots/scripts/test_runner.py
index 88307b1f..51f3ffa8 100644
--- a/ios/build/bots/scripts/test_runner.py
+++ b/ios/build/bots/scripts/test_runner.py
@@ -8,6 +8,7 @@
 import errno
 import glob
 import json
+import logging
 import os
 import plistlib
 import re
@@ -24,9 +25,9 @@
 import xctest_utils
 
 
+LOGGER = logging.getLogger(__name__)
 DERIVED_DATA = os.path.expanduser('~/Library/Developer/Xcode/DerivedData')
 
-
 class Error(Exception):
   """Base class for errors."""
   pass
@@ -345,8 +346,10 @@
       raise XcodeVersionNotFoundError(xcode_build_version)
 
     xcode_info = get_current_xcode_info()
-    print 'Using Xcode version %s build %s at %s' % (
-      xcode_info['version'], xcode_info['build'], xcode_info['path'])
+    LOGGER.info('Using Xcode version %s build %s at %s',
+                 xcode_info['version'],
+                 xcode_info['build'],
+                 xcode_info['path'])
 
     if not os.path.exists(out_dir):
       os.makedirs(out_dir)
@@ -468,6 +471,7 @@
     Returns:
       The previous SIGTERM handler for the test runner.
     """
+    LOGGER.debug('Setting sigterm handler.')
     return signal.signal(signal.SIGTERM, handler)
 
   def handle_sigterm(self, proc):
@@ -479,7 +483,7 @@
     Args:
       proc: The currently executing test process.
     """
-    print "Sigterm caught during test run. Killing test process."
+    LOGGER.warning('Sigterm caught during test run. Killing test process.')
     proc.kill()
 
   def _run(self, cmd, shards=1):
@@ -507,9 +511,9 @@
       thread_pool = pool.ThreadPool(processes=shards)
       for out, name, ret in thread_pool.imap_unordered(
         self.run_tests, test_shards):
-        print "Simulator %s" % name
+        LOGGER.info('Simulator %s', name)
         for line in out:
-          print line
+          LOGGER.info(line)
           parser.ProcessLine(line)
         returncode = ret if ret else 0
       thread_pool.close()
@@ -532,20 +536,22 @@
           break
         line = line.rstrip()
         parser.ProcessLine(line)
-        print line
+        LOGGER.info(line)
         sys.stdout.flush()
 
-      print "Waiting for test process to terminate."
+      LOGGER.info('Waiting for test process to terminate.')
       proc.wait()
-      print "Test process terminated."
+      LOGGER.info('Test process terminated.')
       self.set_sigterm_handler(old_handler)
       sys.stdout.flush()
+      LOGGER.debug('Stdout flushed after test process.')
 
       returncode = proc.returncode
 
     if self.xctest_path and parser.SystemAlertPresent():
       raise SystemAlertPresentError()
 
+    LOGGER.debug('Processing test results.')
     for test in parser.FailedTests(include_flaky=True):
       # Test cases are named as <test group>.<test case>. If the test case
       # is prefixed with "FLAKY_", it should be reported as flaked not failed.
@@ -556,8 +562,7 @@
 
     result.passed_tests.extend(parser.PassedTests(include_flaky=True))
 
-    print '%s returned %s' % (cmd[0], returncode)
-    print
+    LOGGER.info('%s returned %s\n', cmd[0], returncode)
 
     # iossim can return 5 if it exits noncleanly even if all tests passed.
     # Therefore we cannot rely on process exit code to determine success.
@@ -574,8 +579,7 @@
         # If the app crashed but not during any particular test case, assume
         # it crashed on startup. Try one more time.
         self.shutdown_and_restart()
-        print 'Crashed on startup, retrying...'
-        print
+        LOGGER.warning('Crashed on startup, retrying...\n')
         result = self._run(cmd)
 
       if result.crashed and not result.crashed_test:
@@ -591,8 +595,8 @@
           # If the app crashes during a specific test case, then resume at the
           # next test case. This is achieved by filtering out every test case
           # which has already run.
-          print 'Crashed during %s, resuming...' % result.crashed_test
-          print
+          LOGGER.warning('Crashed during %s, resuming...\n',
+                         result.crashed_test)
           result = self._run(self.get_launch_command(
               test_filter=passed + failed.keys() + flaked.keys(), invert=True,
           ))
@@ -601,20 +605,17 @@
           flaked.update(result.flaked_tests)
       except OSError as e:
         if e.errno == errno.E2BIG:
-          print 'Too many test cases to resume.'
-          print
+          LOGGER.error('Too many test cases to resume.')
         else:
           raise
 
       # Retry failed test cases.
       retry_results = {}
       if self.retries and failed:
-        print '%s tests failed and will be retried.' % len(failed)
-        print
+        LOGGER.warning('%s tests failed and will be retried.\n', len(failed))
         for i in xrange(self.retries):
           for test in failed.keys():
-            print 'Retry #%s for %s.' % (i + 1, test)
-            print
+            LOGGER.info('Retry #%s for %s.\n', i + 1, test)
             retry_result = self._run(self.get_launch_command(
                 test_filter=[test]
             ))
@@ -908,10 +909,10 @@
         runtime_id = runtime['identifier']
 
     name = '%s test' % self.platform
-    print 'creating simulator %s' % name
+    LOGGER.info('creating simulator %s', name)
     udid = subprocess.check_output([
       'xcrun', 'simctl', 'create', name, device_type_id, runtime_id]).rstrip()
-    print udid
+    LOGGER.info(udid)
 
     if self.use_trusted_cert:
       if not os.path.exists(self.wpr_tools_path):
@@ -925,7 +926,7 @@
   def deleteSimulator(self, udid=None):
     """Removes dynamically created simulator devices."""
     if udid:
-      print 'deleting simulator %s' % udid
+      LOGGER.info('deleting simulator %s', udid)
       subprocess.call(['xcrun', 'simctl', 'delete', udid])
 
   def get_launch_command(self, test_filter=None, invert=False, test_shard=None):
@@ -1002,7 +1003,7 @@
         '{}/Library/Developer/CoreSimulator/Devices/*/data/Library'.
         format(os.path.expanduser('~')))
     for trustStore in trustStores:
-      print 'Copying TrustStore to {}'.format(trustStore)
+      LOGGER.info('Copying TrustStore to %s', trustStore)
       if not os.path.exists(trustStore + "/Keychains/"):
         os.makedirs(trustStore + "/Keychains/")
       shutil.copy(cert_path, trustStore + "/Keychains/TrustStore.sqlite3")
@@ -1115,7 +1116,7 @@
         the output from the test
     '''
 
-    print 'Running test for recipe {}'.format(recipe_path)
+    LOGGER.info('Running test for recipe %s', recipe_path)
     self.wprgo_start(replay_path)
 
     # TODO(crbug.com/881096): Consider reusing get_launch_command
@@ -1165,7 +1166,7 @@
         break
       line = line.rstrip()
       parser.ProcessLine(line)
-      print line
+      LOGGER.info(line)
       sys.stdout.flush()
 
     proc.wait()
@@ -1191,8 +1192,8 @@
     # If the matching replay for the recipe doesn't exist, don't run it
     replay_path = '{}/{}'.format(self.replay_path, recipe_name)
     if not os.path.isfile(replay_path):
-      print 'No matching replay file for recipe {}'.format(
-        recipe_path)
+      LOGGER.error('No matching replay file for recipe %s',
+                   recipe_name)
       return False
 
     # if there is no filter, then run tests
@@ -1278,8 +1279,7 @@
             total_returncode = returncode
           if parser.CompletedWithoutFailure() == False:
             completed_without_failure = False
-          print '%s test returned %s' % (recipe_path, returncode)
-          print
+          LOGGER.info('%s test returned %s\n', recipe_path, returncode)
 
       self.deleteSimulator(udid)
 
@@ -1506,7 +1506,7 @@
     # in a few hours unexpectedly, which is assumed as an ios beta issue. Should
     # remove this method once the bug is fixed.
     if self.restart:
-      print 'Restarting device, wait for two minutes.'
+      LOGGER.info('Restarting device, wait for two minutes.')
       try:
         subprocess.check_call(
           ['idevicediagnostics', 'restart', '--udid', self.udid])
@@ -1527,7 +1527,7 @@
       ])
     except subprocess.CalledProcessError:
       # TODO(crbug.com/828951): Raise the exception when the bug is fixed.
-      print 'Warning: Failed to retrieve crash reports from the device.'
+      LOGGER.warning('Failed to retrieve crash reports from device.')
 
   def tear_down(self):
     """Performs cleanup actions which must occur after every test launch."""
diff --git a/ios/build/bots/scripts/test_runner_test.py b/ios/build/bots/scripts/test_runner_test.py
index 1da6292..dce3dc8 100755
--- a/ios/build/bots/scripts/test_runner_test.py
+++ b/ios/build/bots/scripts/test_runner_test.py
@@ -7,6 +7,7 @@
 
 import collections
 import glob
+import logging
 import os
 import subprocess
 import unittest
@@ -605,4 +606,6 @@
 
 
 if __name__ == '__main__':
+  logging.basicConfig(format='[%(asctime)s:%(levelname)s] %(message)s',
+    level=logging.DEBUG, datefmt='%I:%M:%S')
   unittest.main()
diff --git a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
index 48debfb..74603e8 100644
--- a/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
+++ b/ios/chrome/browser/ui/signin_interaction/signin_interaction_controller_egtest.mm
@@ -246,7 +246,8 @@
 
 // Tests that signing out of a managed account from the Settings works
 // correctly.
-- (void)testSignInDisconnectFromChromeManaged {
+// TODO(crbug.com): Re-enable the test.
+- (void)DISABLED_testSignInDisconnectFromChromeManaged {
   ChromeIdentity* identity = [SigninEarlGreyUtils fakeManagedIdentity];
   ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
       identity);
diff --git a/ios/chrome/browser/web/BUILD.gn b/ios/chrome/browser/web/BUILD.gn
index fd24fcae..0fbb06adc 100644
--- a/ios/chrome/browser/web/BUILD.gn
+++ b/ios/chrome/browser/web/BUILD.gn
@@ -217,7 +217,7 @@
     "//components/prefs",
     "//components/resources",
     "//components/services/unzip:lib",
-    "//components/services/unzip:manifest",
+    "//components/services/unzip/public/cpp:manifest",
     "//components/services/unzip/public/interfaces",
     "//components/strings",
     "//components/version_info",
@@ -236,7 +236,7 @@
     "//ios/web",
     "//ios/web/public",
     "//net",
-    "//services/identity:manifest",
+    "//services/identity/public/cpp:manifest",
     "//services/identity/public/mojom",
     "//ui/base",
     "//ui/gfx",
diff --git a/ios/chrome/browser/web/DEPS b/ios/chrome/browser/web/DEPS
index 3cd4831..0451482 100644
--- a/ios/chrome/browser/web/DEPS
+++ b/ios/chrome/browser/web/DEPS
@@ -1,5 +1,5 @@
 include_rules = [
-  "+services/identity/manifest.h",
+  "+services/identity/public/cpp/manifest.h",
 ]
 
 specific_include_rules = {
diff --git a/ios/chrome/browser/web/chrome_overlay_manifests.cc b/ios/chrome/browser/web/chrome_overlay_manifests.cc
index e8e5353..509cffd 100644
--- a/ios/chrome/browser/web/chrome_overlay_manifests.cc
+++ b/ios/chrome/browser/web/chrome_overlay_manifests.cc
@@ -5,9 +5,9 @@
 #include "ios/chrome/browser/web/chrome_overlay_manifests.h"
 
 #include "base/no_destructor.h"
-#include "components/services/unzip/manifest.h"
+#include "components/services/unzip/public/cpp/manifest.h"
 #include "components/services/unzip/public/interfaces/constants.mojom.h"
-#include "services/identity/manifest.h"
+#include "services/identity/public/cpp/manifest.h"
 #include "services/identity/public/mojom/constants.mojom.h"
 #include "services/service_manager/public/cpp/manifest_builder.h"
 
@@ -25,7 +25,7 @@
 const service_manager::Manifest& GetChromeWebPackagedServicesOverlayManifest() {
   static base::NoDestructor<service_manager::Manifest> manifest{
       service_manager::ManifestBuilder()
-          .PackageService(unzip_service::GetManifest())
+          .PackageService(unzip::GetManifest())
           .Build()};
 
   return *manifest;
diff --git a/media/base/video_frame.cc b/media/base/video_frame.cc
index 06dd8298..469ff1a 100644
--- a/media/base/video_frame.cc
+++ b/media/base/video_frame.cc
@@ -808,15 +808,14 @@
 
 // static
 void VideoFrame::HashFrameForTesting(base::MD5Context* context,
-                                     const scoped_refptr<VideoFrame>& frame) {
+                                     const VideoFrame& frame) {
   DCHECK(context);
-  for (size_t plane = 0; plane < NumPlanes(frame->format()); ++plane) {
-    for (int row = 0; row < frame->rows(plane); ++row) {
-      base::MD5Update(
-          context,
-          base::StringPiece(reinterpret_cast<char*>(frame->data(plane) +
-                                                    frame->stride(plane) * row),
-                            frame->row_bytes(plane)));
+  for (size_t plane = 0; plane < NumPlanes(frame.format()); ++plane) {
+    for (int row = 0; row < frame.rows(plane); ++row) {
+      base::MD5Update(context, base::StringPiece(reinterpret_cast<const char*>(
+                                                     frame.data(plane) +
+                                                     frame.stride(plane) * row),
+                                                 frame.row_bytes(plane)));
     }
   }
 }
diff --git a/media/base/video_frame.h b/media/base/video_frame.h
index d8e7afe..bb7011a 100644
--- a/media/base/video_frame.h
+++ b/media/base/video_frame.h
@@ -346,7 +346,7 @@
   // Used to keep a running hash of seen frames.  Expects an initialized MD5
   // context.  Calls MD5Update with the context and the contents of the frame.
   static void HashFrameForTesting(base::MD5Context* context,
-                                  const scoped_refptr<VideoFrame>& frame);
+                                  const VideoFrame& frame);
 
   // Returns true if |frame| is accesible mapped in the VideoFrame memory space.
   // static
diff --git a/media/base/video_frame_unittest.cc b/media/base/video_frame_unittest.cc
index c0a78ff2..be4c477a 100644
--- a/media/base/video_frame_unittest.cc
+++ b/media/base/video_frame_unittest.cc
@@ -143,7 +143,7 @@
 
   base::MD5Context context;
   base::MD5Init(&context);
-  VideoFrame::HashFrameForTesting(&context, frame);
+  VideoFrame::HashFrameForTesting(&context, *frame.get());
   base::MD5Digest digest;
   base::MD5Final(&digest, &context);
   EXPECT_EQ(MD5DigestToBase16(digest), expected_hash);
@@ -170,7 +170,7 @@
   base::MD5Digest digest;
   base::MD5Context context;
   base::MD5Init(&context);
-  VideoFrame::HashFrameForTesting(&context, frame);
+  VideoFrame::HashFrameForTesting(&context, *frame.get());
   base::MD5Final(&digest, &context);
   EXPECT_EQ(MD5DigestToBase16(digest), "9065c841d9fca49186ef8b4ef547e79b");
   {
@@ -179,7 +179,7 @@
     ExpectFrameColor(frame.get(), 0xFFFFFFFF);
   }
   base::MD5Init(&context);
-  VideoFrame::HashFrameForTesting(&context, frame);
+  VideoFrame::HashFrameForTesting(&context, *frame.get());
   base::MD5Final(&digest, &context);
   EXPECT_EQ(MD5DigestToBase16(digest), "911991d51438ad2e1a40ed5f6fc7c796");
 
diff --git a/media/gpu/image_processor_test.cc b/media/gpu/image_processor_test.cc
index c7a2048..e1c18d07 100644
--- a/media/gpu/image_processor_test.cc
+++ b/media/gpu/image_processor_test.cc
@@ -87,7 +87,7 @@
   ASSERT_TRUE(processed_frame->IsMappable());
   base::MD5Context context;
   base::MD5Init(&context);
-  VideoFrame::HashFrameForTesting(&context, processed_frame);
+  VideoFrame::HashFrameForTesting(&context, *processed_frame.get());
   base::MD5Digest digest;
   base::MD5Final(&digest, &context);
   std::string expected_md5 = output_image.Checksum();
diff --git a/media/gpu/test/video_frame_validator.cc b/media/gpu/test/video_frame_validator.cc
index 6b5fa03..b05b9b2 100644
--- a/media/gpu/test/video_frame_validator.cc
+++ b/media/gpu/test/video_frame_validator.cc
@@ -20,7 +20,7 @@
 
 // static
 std::unique_ptr<VideoFrameValidator> VideoFrameValidator::Create(
-    const std::vector<std::string>& frame_checksums) {
+    const std::vector<std::string>& expected_frame_checksums) {
   auto video_frame_mapper = VideoFrameMapperFactory::CreateMapper();
   if (!video_frame_mapper) {
     LOG(ERROR) << "Failed to create VideoFrameMapper.";
@@ -28,8 +28,8 @@
   }
 
   auto video_frame_validator = base::WrapUnique(new VideoFrameValidator(
-      VideoFrameValidator::CHECK, base::FilePath(), frame_checksums,
-      base::File(), std::move(video_frame_mapper)));
+      VideoFrameValidator::CHECK, base::FilePath(), expected_frame_checksums,
+      std::move(video_frame_mapper)));
   if (!video_frame_validator->Initialize()) {
     LOG(ERROR) << "Failed to initialize VideoFrameValidator.";
     return nullptr;
@@ -42,46 +42,21 @@
 std::unique_ptr<VideoFrameValidator> VideoFrameValidator::Create(
     uint32_t flags,
     const base::FilePath& prefix_output_yuv,
-    const base::FilePath& md5_file_path,
-    bool linear) {
+    const std::vector<std::string>& expected_frame_checksums) {
   if ((flags & VideoFrameValidator::OUTPUTYUV) && prefix_output_yuv.empty()) {
     LOG(ERROR) << "Prefix of yuv files isn't specified with dump flags.";
     return nullptr;
   }
 
-  if ((flags & VideoFrameValidator::GENMD5) &&
-      (flags & VideoFrameValidator::CHECK)) {
-    LOG(ERROR) << "Generating and checking MD5 values at the same time is not "
-               << "supported.";
-  }
-  auto video_frame_mapper = VideoFrameMapperFactory::CreateMapper(linear);
+  auto video_frame_mapper = VideoFrameMapperFactory::CreateMapper();
 
   if (!video_frame_mapper) {
     LOG(ERROR) << "Failed to create VideoFrameMapper.";
     return nullptr;
   }
 
-  std::vector<std::string> md5_of_frames;
-  base::File md5_file;
-  if (flags & VideoFrameValidator::GENMD5) {
-    // Writes out computed md5 values to md5_file_path.
-    md5_file = base::File(md5_file_path, base::File::FLAG_CREATE_ALWAYS |
-                                             base::File::FLAG_WRITE |
-                                             base::File::FLAG_APPEND);
-    if (!md5_file.IsValid()) {
-      LOG(ERROR) << "Failed to create md5 file to write " << md5_file_path;
-      return nullptr;
-    }
-  } else if (flags & VideoFrameValidator::CHECK) {
-    md5_of_frames = ReadGoldenThumbnailMD5s(md5_file_path);
-    if (md5_of_frames.empty()) {
-      LOG(ERROR) << "Failed to read md5 values in " << md5_file_path;
-      return nullptr;
-    }
-  }
-
   auto video_frame_validator = base::WrapUnique(new VideoFrameValidator(
-      flags, prefix_output_yuv, std::move(md5_of_frames), std::move(md5_file),
+      flags, prefix_output_yuv, std::move(expected_frame_checksums),
       std::move(video_frame_mapper)));
   if (!video_frame_validator->Initialize()) {
     LOG(ERROR) << "Failed to initialize VideoFrameValidator.";
@@ -94,13 +69,11 @@
 VideoFrameValidator::VideoFrameValidator(
     uint32_t flags,
     const base::FilePath& prefix_output_yuv,
-    std::vector<std::string> md5_of_frames,
-    base::File md5_file,
+    std::vector<std::string> expected_frame_checksums,
     std::unique_ptr<VideoFrameMapper> video_frame_mapper)
     : flags_(flags),
       prefix_output_yuv_(prefix_output_yuv),
-      md5_of_frames_(std::move(md5_of_frames)),
-      md5_file_(std::move(md5_file)),
+      expected_frame_checksums_(std::move(expected_frame_checksums)),
       video_frame_mapper_(std::move(video_frame_mapper)),
       num_frames_validating_(0),
       frame_validator_thread_("FrameValidatorThread"),
@@ -127,6 +100,10 @@
   DCHECK_EQ(0u, num_frames_validating_);
 }
 
+const std::vector<std::string>& VideoFrameValidator::GetFrameChecksums() const {
+  return frame_checksums_;
+}
+
 std::vector<VideoFrameValidator::MismatchedFrameInfo>
 VideoFrameValidator::GetMismatchedFramesInfo() const {
   base::AutoLock auto_lock(frame_validator_lock_);
@@ -177,17 +154,15 @@
     return;
   }
   std::string computed_md5 = ComputeMD5FromVideoFrame(standard_frame);
-  if (flags_ & Flags::GENMD5) {
-    md5_file_.Write(0, computed_md5.data(), computed_md5.size());
-    md5_file_.Write(0, "\n", 1);
-  }
+
+  base::AutoLock auto_lock(frame_validator_lock_);
+  frame_checksums_.push_back(computed_md5);
 
   if (flags_ & Flags::CHECK) {
-    LOG_IF(FATAL, frame_index >= md5_of_frames_.size())
+    LOG_IF(FATAL, frame_index >= expected_frame_checksums_.size())
         << "Frame number is over than the number of read md5 values in file.";
-    const auto& expected_md5 = md5_of_frames_[frame_index];
+    const auto& expected_md5 = expected_frame_checksums_[frame_index];
     if (computed_md5 != expected_md5) {
-      base::AutoLock auto_lock(frame_validator_lock_);
       mismatched_frames_.push_back(
           MismatchedFrameInfo{frame_index, computed_md5, expected_md5});
     }
@@ -198,7 +173,6 @@
         << "Failed to write yuv into file.";
   }
 
-  base::AutoLock auto_lock(frame_validator_lock_);
   num_frames_validating_--;
   frame_validator_cv_.Signal();
 }
@@ -220,7 +194,7 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(validator_thread_sequence_checker_);
   base::MD5Context context;
   base::MD5Init(&context);
-  VideoFrame::HashFrameForTesting(&context, video_frame);
+  VideoFrame::HashFrameForTesting(&context, *video_frame.get());
   base::MD5Digest digest;
   base::MD5Final(&digest, &context);
   return MD5DigestToBase16(digest);
diff --git a/media/gpu/test/video_frame_validator.h b/media/gpu/test/video_frame_validator.h
index 60813be..36d3c13d 100644
--- a/media/gpu/test/video_frame_validator.h
+++ b/media/gpu/test/video_frame_validator.h
@@ -45,8 +45,6 @@
     CHECK = 1 << 0,
     // Writes out video frames to files.
     OUTPUTYUV = 1 << 1,
-    // Writes out md5 values to a file.
-    GENMD5 = 1 << 2,
   };
 
   struct MismatchedFrameInfo {
@@ -59,26 +57,26 @@
   // |frame_checksums| should contain the ordered list of md5 frame checksums to
   // be used by the validator
   static std::unique_ptr<VideoFrameValidator> Create(
-      const std::vector<std::string>& frame_checksums);
+      const std::vector<std::string>& expected_frame_checksums);
 
   // |flags| decides the behavior of created video frame validator. See the
   // detail in Flags.
   // |prefix_output_yuv| is the prefix name of saved yuv files.
   // VideoFrameValidator saves all I420 video frames.
   // If |prefix_output_yuv_| is not specified, no yuv file will be saved.
-  // |md5_file_path| is the path to the file that contains golden md5 values.
-  // The file contains one md5 value per line, listed in display order.
-  // |linear| represents whether VideoFrame passed on EvaludateVideoFrame() is
-  // linear (i.e non-tiled) or not.
+  // |frame_checksums| should contain the ordered list of md5 frame checksums to
+  // be used by the validator.
   // Returns nullptr on failure.
   static std::unique_ptr<VideoFrameValidator> Create(
       uint32_t flags,
       const base::FilePath& prefix_output_yuv,
-      const base::FilePath& md5_file_path,
-      bool linear);
+      const std::vector<std::string>& frame_checksums);
 
   ~VideoFrameValidator() override;
 
+  // Get the ordered list of calculated frame checksums.
+  const std::vector<std::string>& GetFrameChecksums() const;
+
   // Returns information of frames that don't match golden md5 values.
   // If there is no mismatched frame, returns an empty vector. This function is
   // thread-safe.
@@ -100,7 +98,6 @@
   VideoFrameValidator(uint32_t flags,
                       const base::FilePath& prefix_output_yuv,
                       std::vector<std::string> md5_of_frames,
-                      base::File md5_file,
                       std::unique_ptr<VideoFrameMapper> video_frame_mapper);
 
   // Start the frame validation thread.
@@ -136,11 +133,11 @@
   // Prefix of saved yuv files.
   const base::FilePath prefix_output_yuv_;
 
-  // Golden MD5 values.
-  std::vector<std::string> md5_of_frames_;
+  // The list of calculated MD5 frame checksums.
+  std::vector<std::string> frame_checksums_ GUARDED_BY(frame_validator_lock_);
 
-  // File to write md5 values if flags includes GENMD5.
-  base::File md5_file_;
+  // The list of golden MD5 frame checksums.
+  const std::vector<std::string> expected_frame_checksums_;
 
   const std::unique_ptr<VideoFrameMapper> video_frame_mapper_;
 
diff --git a/media/gpu/v4l2/v4l2_image_processor.cc b/media/gpu/v4l2/v4l2_image_processor.cc
index 01b063e..decc5c8b 100644
--- a/media/gpu/v4l2/v4l2_image_processor.cc
+++ b/media/gpu/v4l2/v4l2_image_processor.cc
@@ -438,9 +438,25 @@
             << job_record->output_buffer_index;
   DCHECK_CALLED_ON_VALID_THREAD(device_thread_checker_);
 
-  EnqueueOutput(job_record.get());
   input_job_queue_.emplace(std::move(job_record));
-  EnqueueInput();
+  ProcessJobsTask();
+}
+
+void V4L2ImageProcessor::ProcessJobsTask() {
+  DCHECK_CALLED_ON_VALID_THREAD(device_thread_checker_);
+
+  while (!input_job_queue_.empty()) {
+    // The output buffer is already decided, but we need one free input buffer
+    // to schedule the job
+    if (input_queue_->FreeBuffersCount() == 0)
+      break;
+
+    auto job_record = std::move(input_job_queue_.front());
+    input_job_queue_.pop();
+    EnqueueInput(job_record.get());
+    EnqueueOutput(job_record.get());
+    running_jobs_.emplace(std::move(job_record));
+  }
 }
 
 bool V4L2ImageProcessor::Reset() {
@@ -641,7 +657,7 @@
     return;
 
   Dequeue();
-  EnqueueInput();
+  ProcessJobsTask();
 
   if (!device_->ClearDevicePollInterrupt()) {
     NotifyError();
@@ -664,15 +680,14 @@
             << "]";
 }
 
-void V4L2ImageProcessor::EnqueueInput() {
+void V4L2ImageProcessor::EnqueueInput(const JobRecord* job_record) {
   DVLOGF(4);
   DCHECK_CALLED_ON_VALID_THREAD(device_thread_checker_);
 
   const size_t old_inputs_queued = input_queue_->QueuedBuffersCount();
-  while (!input_job_queue_.empty() && input_queue_->FreeBuffersCount() > 0) {
-    if (!EnqueueInputRecord())
-      return;
-  }
+  if (!EnqueueInputRecord(job_record))
+    return;
+
   if (old_inputs_queued == 0 && input_queue_->QueuedBuffersCount() != 0) {
     // We started up a previously empty queue.
     // Queue state changed; signal interrupt.
@@ -764,14 +779,11 @@
   }
 }
 
-bool V4L2ImageProcessor::EnqueueInputRecord() {
+bool V4L2ImageProcessor::EnqueueInputRecord(const JobRecord* job_record) {
   DVLOGF(4);
-  DCHECK(!input_job_queue_.empty());
   DCHECK_GT(input_queue_->FreeBuffersCount(), 0u);
 
   // Enqueue an input (VIDEO_OUTPUT) buffer for an input video frame.
-  std::unique_ptr<JobRecord> job_record = std::move(input_job_queue_.front());
-  input_job_queue_.pop();
   V4L2WritableBufferRef buffer(input_queue_->GetFreeBuffer());
   DCHECK(buffer.IsValid());
 
@@ -800,8 +812,6 @@
             << job_record->input_frame->timestamp().InMilliseconds()
             << " to device.";
 
-  running_jobs_.emplace(std::move(job_record));
-
   return true;
 }
 
diff --git a/media/gpu/v4l2/v4l2_image_processor.h b/media/gpu/v4l2/v4l2_image_processor.h
index 3898056..7fd520e 100644
--- a/media/gpu/v4l2/v4l2_image_processor.h
+++ b/media/gpu/v4l2/v4l2_image_processor.h
@@ -117,10 +117,10 @@
                      ErrorCB error_cb);
 
   bool Initialize();
-  void EnqueueInput();
+  void EnqueueInput(const JobRecord* job_record);
   void EnqueueOutput(const JobRecord* job_record);
   void Dequeue();
-  bool EnqueueInputRecord();
+  bool EnqueueInputRecord(const JobRecord* job_record);
   bool EnqueueOutputRecord(const JobRecord* job_record);
   bool CreateInputBuffers();
   bool CreateOutputBuffers();
@@ -139,6 +139,7 @@
                        FrameReadyCB cb) override;
 
   void ProcessTask(std::unique_ptr<JobRecord> job_record);
+  void ProcessJobsTask();
   void ServiceDeviceTask();
 
   // Allocate/Destroy the input/output V4L2 buffers.
diff --git a/media/gpu/video_decode_accelerator_unittest.cc b/media/gpu/video_decode_accelerator_unittest.cc
index 0702f890..169ff4b 100644
--- a/media/gpu/video_decode_accelerator_unittest.cc
+++ b/media/gpu/video_decode_accelerator_unittest.cc
@@ -1162,14 +1162,21 @@
       prefix_output_yuv = GetTestDataFile(filepath);
     }
   }
-#if BUILDFLAG(USE_VAAPI)
-  bool linear = false;
-#else
-  bool linear = true;
-#endif
+
+  // Read md5 frame checksums.
+  std::vector<std::string> frame_checksums;
+  if (g_frame_validator_flags & test::VideoFrameValidator::CHECK) {
+    base::FilePath md5_file_path =
+        filepath.AddExtension(FILE_PATH_LITERAL(".frames.md5"));
+    frame_checksums = test::ReadGoldenThumbnailMD5s(md5_file_path);
+    if (frame_checksums.empty()) {
+      LOG(ERROR) << "Failed to read md5 values in " << md5_file_path;
+      return nullptr;
+    }
+  }
+
   return media::test::VideoFrameValidator::Create(
-      g_frame_validator_flags, prefix_output_yuv,
-      filepath.AddExtension(FILE_PATH_LITERAL(".frames.md5")), linear);
+      g_frame_validator_flags, prefix_output_yuv, frame_checksums);
 }
 
 // Fails on Win only. crbug.com/849368
@@ -1663,7 +1670,7 @@
 // --gtest_filter=VideoDecodeAcceleratorTest.DISABLED_GenMD5 and
 // --gtest_also_run_disabled_tests
 TEST_F(VideoDecodeAcceleratorTest, DISABLED_GenMD5) {
-  g_frame_validator_flags = test::VideoFrameValidator::GENMD5;
+  g_frame_validator_flags = 0;
   g_test_import = true;
 
   ASSERT_EQ(test_video_files_.size(), 1u);
@@ -1677,6 +1684,8 @@
   config.num_frames = video_file->num_frames;
   auto video_frame_validator =
       CreateAndInitializeVideoFrameValidator(video_file->file_name);
+  media::test::VideoFrameValidator* frame_validator =
+      video_frame_validator.get();
   clients_.push_back(std::make_unique<GLRenderingVDAClient>(
       std::move(config), video_file->data_str, &rendering_helper_,
       std::move(video_frame_validator), notes_[0].get()));
@@ -1687,8 +1696,23 @@
   ClientState last_state = WaitUntilDecodeFinish(notes_[0].get());
   EXPECT_NE(CS_ERROR, last_state);
 
+  // Write out computed md5 values.
+  frame_validator->WaitUntilDone();
+  const std::vector<std::string>& frame_checksums =
+      frame_validator->GetFrameChecksums();
+  base::FilePath md5_file_path(video_file->file_name);
+  base::File md5_file(md5_file_path, base::File::FLAG_CREATE_ALWAYS |
+                                         base::File::FLAG_WRITE |
+                                         base::File::FLAG_APPEND);
+  if (!md5_file.IsValid())
+    LOG(ERROR) << "Failed to create md5 file to write " << md5_file_path;
+
+  for (const std::string& frame_checksum : frame_checksums) {
+    md5_file.Write(0, frame_checksum.data(), frame_checksum.size());
+    md5_file.Write(0, "\n", 1);
+  }
+
   g_test_import = false;
-  g_frame_validator_flags = 0;
 }
 #endif
 
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc
index 8a62d4f..5634979 100644
--- a/media/test/pipeline_integration_test_base.cc
+++ b/media/test/pipeline_integration_test_base.cc
@@ -549,7 +549,7 @@
     return;
   last_frame_ = frame;
   DVLOG(3) << __func__ << " pts=" << frame->timestamp().InSecondsF();
-  VideoFrame::HashFrameForTesting(&md5_context_, frame);
+  VideoFrame::HashFrameForTesting(&md5_context_, *frame.get());
 }
 
 void PipelineIntegrationTestBase::CheckDuration() {
diff --git a/net/dns/address_sorter_posix_unittest.cc b/net/dns/address_sorter_posix_unittest.cc
index 5e8eabc..8f34bc9 100644
--- a/net/dns/address_sorter_posix_unittest.cc
+++ b/net/dns/address_sorter_posix_unittest.cc
@@ -189,6 +189,21 @@
     NOTIMPLEMENTED();
     return nullptr;
   }
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
   void AddMapping(const IPAddress& dst, const IPAddress& src) {
     mapping_[dst] = src;
   }
diff --git a/net/dns/dns_session_unittest.cc b/net/dns/dns_session_unittest.cc
index 80d4d4d..5789ed97 100644
--- a/net/dns/dns_session_unittest.cc
+++ b/net/dns/dns_session_unittest.cc
@@ -78,6 +78,22 @@
     return nullptr;
   }
 
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
+
  private:
   std::list<std::unique_ptr<SocketDataProvider>> data_providers_;
 };
diff --git a/net/http/http_proxy_client_socket.cc b/net/http/http_proxy_client_socket.cc
index d5cbf07..6c57135 100644
--- a/net/http/http_proxy_client_socket.cc
+++ b/net/http/http_proxy_client_socket.cc
@@ -23,6 +23,7 @@
 #include "net/log/net_log.h"
 #include "net/log/net_log_event_type.h"
 #include "net/socket/client_socket_handle.h"
+#include "net/socket/stream_socket.h"
 #include "url/gurl.h"
 
 namespace net {
@@ -30,7 +31,7 @@
 const int HttpProxyClientSocket::kDrainBodyBufferSize;
 
 HttpProxyClientSocket::HttpProxyClientSocket(
-    std::unique_ptr<ClientSocketHandle> transport_socket,
+    std::unique_ptr<StreamSocket> stream_socket,
     const std::string& user_agent,
     const HostPortPair& endpoint,
     const ProxyServer& proxy_server,
@@ -44,7 +45,9 @@
     : io_callback_(base::BindRepeating(&HttpProxyClientSocket::OnIOComplete,
                                        base::Unretained(this))),
       next_state_(STATE_NONE),
-      transport_(std::move(transport_socket)),
+      stream_socket_(std::move(stream_socket)),
+      socket_(stream_socket_.get()),
+      is_reused_(false),
       endpoint_(endpoint),
       auth_(http_auth_controller),
       tunnel_(tunnel),
@@ -54,8 +57,44 @@
       proxy_server_(proxy_server),
       proxy_delegate_(proxy_delegate),
       traffic_annotation_(traffic_annotation),
-      net_log_(transport_->socket()->NetLog()) {
-  // Synthesize the bits of a request that we actually use.
+      net_log_(socket_->NetLog()) {
+  // Synthesize the bits of a request that are actually used.
+  request_.url = GURL("https://" + endpoint.ToString());
+  request_.method = "CONNECT";
+  if (!user_agent.empty())
+    request_.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
+                                     user_agent);
+}
+
+HttpProxyClientSocket::HttpProxyClientSocket(
+    std::unique_ptr<ClientSocketHandle> client_socket_handle,
+    const std::string& user_agent,
+    const HostPortPair& endpoint,
+    const ProxyServer& proxy_server,
+    HttpAuthController* http_auth_controller,
+    bool tunnel,
+    bool using_spdy,
+    NextProto negotiated_protocol,
+    ProxyDelegate* proxy_delegate,
+    bool is_https_proxy,
+    const NetworkTrafficAnnotationTag& traffic_annotation)
+    : io_callback_(base::BindRepeating(&HttpProxyClientSocket::OnIOComplete,
+                                       base::Unretained(this))),
+      next_state_(STATE_NONE),
+      client_socket_handle_(std::move(client_socket_handle)),
+      socket_(client_socket_handle_->socket()),
+      is_reused_(client_socket_handle_->is_reused()),
+      endpoint_(endpoint),
+      auth_(http_auth_controller),
+      tunnel_(tunnel),
+      using_spdy_(using_spdy),
+      negotiated_protocol_(negotiated_protocol),
+      is_https_proxy_(is_https_proxy),
+      proxy_server_(proxy_server),
+      proxy_delegate_(proxy_delegate),
+      traffic_annotation_(traffic_annotation),
+      net_log_(socket_->NetLog()) {
+  // Synthesize the bits of a request that are actually used.
   request_.url = GURL("https://" + endpoint.ToString());
   request_.method = "CONNECT";
   if (!user_agent.empty())
@@ -102,8 +141,7 @@
 }
 
 int HttpProxyClientSocket::Connect(CompletionOnceCallback callback) {
-  DCHECK(transport_.get());
-  DCHECK(transport_->socket());
+  DCHECK(socket_);
   DCHECK(user_callback_.is_null());
 
   // TODO(rch): figure out the right way to set up a tunnel with SPDY.
@@ -126,8 +164,8 @@
 }
 
 void HttpProxyClientSocket::Disconnect() {
-  if (transport_.get())
-    transport_->socket()->Disconnect();
+  if (socket_)
+    socket_->Disconnect();
 
   // Reset other states to make sure they aren't mistakenly used later.
   // These are the states initialized by Connect().
@@ -136,12 +174,11 @@
 }
 
 bool HttpProxyClientSocket::IsConnected() const {
-  return next_state_ == STATE_DONE && transport_->socket()->IsConnected();
+  return next_state_ == STATE_DONE && socket_->IsConnected();
 }
 
 bool HttpProxyClientSocket::IsConnectedAndIdle() const {
-  return next_state_ == STATE_DONE &&
-    transport_->socket()->IsConnectedAndIdle();
+  return next_state_ == STATE_DONE && socket_->IsConnectedAndIdle();
 }
 
 const NetLogWithSource& HttpProxyClientSocket::NetLog() const {
@@ -149,33 +186,29 @@
 }
 
 bool HttpProxyClientSocket::WasEverUsed() const {
-  if (transport_.get() && transport_->socket()) {
-    return transport_->socket()->WasEverUsed();
-  }
+  if (socket_)
+    return socket_->WasEverUsed();
   NOTREACHED();
   return false;
 }
 
 bool HttpProxyClientSocket::WasAlpnNegotiated() const {
-  if (transport_.get() && transport_->socket()) {
-    return transport_->socket()->WasAlpnNegotiated();
-  }
+  if (socket_)
+    return socket_->WasAlpnNegotiated();
   NOTREACHED();
   return false;
 }
 
 NextProto HttpProxyClientSocket::GetNegotiatedProtocol() const {
-  if (transport_.get() && transport_->socket()) {
-    return transport_->socket()->GetNegotiatedProtocol();
-  }
+  if (socket_)
+    return socket_->GetNegotiatedProtocol();
   NOTREACHED();
   return kProtoUnknown;
 }
 
 bool HttpProxyClientSocket::GetSSLInfo(SSLInfo* ssl_info) {
-  if (transport_.get() && transport_->socket()) {
-    return transport_->socket()->GetSSLInfo(ssl_info);
-  }
+  if (socket_)
+    return socket_->GetSSLInfo(ssl_info);
   NOTREACHED();
   return false;
 }
@@ -186,11 +219,11 @@
 }
 
 int64_t HttpProxyClientSocket::GetTotalReceivedBytes() const {
-  return transport_->socket()->GetTotalReceivedBytes();
+  return socket_->GetTotalReceivedBytes();
 }
 
 void HttpProxyClientSocket::ApplySocketTag(const SocketTag& tag) {
-  return transport_->socket()->ApplySocketTag(tag);
+  return socket_->ApplySocketTag(tag);
 }
 
 int HttpProxyClientSocket::Read(IOBuffer* buf,
@@ -200,7 +233,7 @@
   if (!CheckDone())
     return ERR_TUNNEL_CONNECTION_FAILED;
 
-  return transport_->socket()->Read(buf, buf_len, std::move(callback));
+  return socket_->Read(buf, buf_len, std::move(callback));
 }
 
 int HttpProxyClientSocket::ReadIfReady(IOBuffer* buf,
@@ -210,11 +243,11 @@
   if (!CheckDone())
     return ERR_TUNNEL_CONNECTION_FAILED;
 
-  return transport_->socket()->ReadIfReady(buf, buf_len, std::move(callback));
+  return socket_->ReadIfReady(buf, buf_len, std::move(callback));
 }
 
 int HttpProxyClientSocket::CancelReadIfReady() {
-  return transport_->socket()->CancelReadIfReady();
+  return socket_->CancelReadIfReady();
 }
 
 int HttpProxyClientSocket::Write(
@@ -225,24 +258,23 @@
   DCHECK_EQ(STATE_DONE, next_state_);
   DCHECK(user_callback_.is_null());
 
-  return transport_->socket()->Write(buf, buf_len, std::move(callback),
-                                     traffic_annotation);
+  return socket_->Write(buf, buf_len, std::move(callback), traffic_annotation);
 }
 
 int HttpProxyClientSocket::SetReceiveBufferSize(int32_t size) {
-  return transport_->socket()->SetReceiveBufferSize(size);
+  return socket_->SetReceiveBufferSize(size);
 }
 
 int HttpProxyClientSocket::SetSendBufferSize(int32_t size) {
-  return transport_->socket()->SetSendBufferSize(size);
+  return socket_->SetSendBufferSize(size);
 }
 
 int HttpProxyClientSocket::GetPeerAddress(IPEndPoint* address) const {
-  return transport_->socket()->GetPeerAddress(address);
+  return socket_->GetPeerAddress(address);
 }
 
 int HttpProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
-  return transport_->socket()->GetLocalAddress(address);
+  return socket_->GetLocalAddress(address);
 }
 
 int HttpProxyClientSocket::PrepareForAuthRestart() {
@@ -253,9 +285,8 @@
   // ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH.  The request will be retried
   // at a higher layer.
   if (!response_.headers->IsKeepAlive() ||
-      !http_stream_parser_->CanFindEndOfResponse() ||
-      !transport_->socket()->IsConnected()) {
-    transport_->socket()->Disconnect();
+      !http_stream_parser_->CanFindEndOfResponse() || !socket_->IsConnected()) {
+    socket_->Disconnect();
     return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH;
   }
 
@@ -271,11 +302,11 @@
 
 int HttpProxyClientSocket::DidDrainBodyForAuthRestart() {
   // Can't reuse the socket if there's still unread data on it.
-  if (!transport_->socket()->IsConnectedAndIdle())
+  if (!socket_->IsConnectedAndIdle())
     return ERR_UNABLE_TO_REUSE_CONNECTION_FOR_PROXY_AUTH;
 
   next_state_ = STATE_GENERATE_AUTH_TOKEN;
-  transport_->set_reuse_type(ClientSocketHandle::REUSED_IDLE);
+  is_reused_ = true;
 
   // Reset the other member variables.
   drain_buf_ = nullptr;
@@ -406,9 +437,8 @@
   }
 
   parser_buf_ = base::MakeRefCounted<GrowableIOBuffer>();
-  http_stream_parser_.reset(
-      new HttpStreamParser(transport_->socket(), transport_->is_reused(),
-                           &request_, parser_buf_.get(), net_log_));
+  http_stream_parser_.reset(new HttpStreamParser(socket_, is_reused_, &request_,
+                                                 parser_buf_.get(), net_log_));
   return http_stream_parser_->SendRequest(request_line_, request_headers_,
                                           traffic_annotation_, &response_,
                                           io_callback_);
@@ -473,7 +503,10 @@
         return ERR_TUNNEL_CONNECTION_FAILED;
 
       http_stream_parser_.reset();
-      transport_.reset();
+      client_socket_handle_.reset();
+      stream_socket_.reset();
+      socket_ = nullptr;
+      is_reused_ = false;
       return ERR_HTTPS_PROXY_TUNNEL_RESPONSE;
 
     case 407:  // Proxy Authentication Required
diff --git a/net/http/http_proxy_client_socket.h b/net/http/http_proxy_client_socket.h
index 5c4580f..2585e9a0 100644
--- a/net/http/http_proxy_client_socket.h
+++ b/net/http/http_proxy_client_socket.h
@@ -34,13 +34,15 @@
 class HttpStreamParser;
 class IOBuffer;
 class ProxyDelegate;
+class StreamSocket;
 
 class NET_EXPORT_PRIVATE HttpProxyClientSocket : public ProxyClientSocket {
  public:
-  // Takes ownership of |transport_socket|, which should already be connected
-  // by the time Connect() is called.  If tunnel is true then on Connect()
-  // this socket will establish an Http tunnel.
-  HttpProxyClientSocket(std::unique_ptr<ClientSocketHandle> transport_socket,
+  // Takes ownership of |stream_socket|, which should already be connected
+  // by the time Connect() is called. |stream_socket_| is assumed to be a freash
+  // socket. If tunnel is true then on Connect() this socket will establish an
+  // Http tunnel.
+  HttpProxyClientSocket(std::unique_ptr<StreamSocket> stream_socket,
                         const std::string& user_agent,
                         const HostPortPair& endpoint,
                         const ProxyServer& proxy_server,
@@ -52,6 +54,21 @@
                         bool is_https_proxy,
                         const NetworkTrafficAnnotationTag& traffic_annotation);
 
+  // Same as above, but takes a ClientSocketHandle instead.
+  // TODO(mmenke): Remove in favor of above constructor.
+  HttpProxyClientSocket(
+      std::unique_ptr<ClientSocketHandle> client_socket_handle,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation);
+
   // On destruction Disconnect() is called.
   ~HttpProxyClientSocket() override;
 
@@ -146,8 +163,16 @@
   std::unique_ptr<HttpStreamParser> http_stream_parser_;
   scoped_refptr<IOBuffer> drain_buf_;
 
-  // Stores the underlying socket.
-  std::unique_ptr<ClientSocketHandle> transport_;
+  // One of these two stores the underlying socket, depending on which
+  // constructor was used.
+  std::unique_ptr<ClientSocketHandle> client_socket_handle_;
+  std::unique_ptr<StreamSocket> stream_socket_;
+  // The underlying socket.
+  StreamSocket* socket_;
+
+  // Whether or not |socket_| has been previously used. Once auth credentials
+  // are sent, set to true.
+  bool is_reused_;
 
   // The hostname and port of the endpoint.  This is not necessarily the one
   // specified by the URL, due to Alternate-Protocol or fixed testing ports.
diff --git a/net/http/http_proxy_client_socket_unittest.cc b/net/http/http_proxy_client_socket_unittest.cc
index d4d11b99..226a671 100644
--- a/net/http/http_proxy_client_socket_unittest.cc
+++ b/net/http/http_proxy_client_socket_unittest.cc
@@ -8,7 +8,6 @@
 #include "net/base/address_list.h"
 #include "net/base/host_port_pair.h"
 #include "net/base/proxy_server.h"
-#include "net/log/test_net_log.h"
 #include "net/socket/next_proto.h"
 #include "net/socket/socket_tag.h"
 #include "net/socket/socket_test_util.h"
@@ -21,18 +20,16 @@
 
 TEST(HttpProxyClientSocketTest, Tag) {
   StaticSocketDataProvider data;
-  TestNetLog log;
   MockTaggingStreamSocket* tagging_sock =
-      new MockTaggingStreamSocket(std::unique_ptr<StreamSocket>(
-          new MockTCPClientSocket(AddressList(), &log, &data)));
+      new MockTaggingStreamSocket(std::make_unique<MockTCPClientSocket>(
+          AddressList(), nullptr /* net_log */, &data));
 
-  std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
-  // |connection| takes ownership of |tagging_sock|, but keep a
-  // non-owning pointer to it.
-  connection->SetSocket(std::unique_ptr<StreamSocket>(tagging_sock));
-  HttpProxyClientSocket socket(
-      std::move(connection), "", HostPortPair(), ProxyServer(), nullptr, false,
-      false, NextProto(), nullptr, false, TRAFFIC_ANNOTATION_FOR_TESTS);
+  // |socket| takes ownership of |tagging_sock|, but the test keeps a non-owning
+  // pointer to it.
+  HttpProxyClientSocket socket(std::unique_ptr<StreamSocket>(tagging_sock), "",
+                               HostPortPair(), ProxyServer(), nullptr, false,
+                               false, NextProto(), nullptr, false,
+                               TRAFFIC_ANNOTATION_FOR_TESTS);
 
   EXPECT_EQ(tagging_sock->tag(), SocketTag());
 #if defined(OS_ANDROID)
diff --git a/net/proxy_resolution/pac_library_unittest.cc b/net/proxy_resolution/pac_library_unittest.cc
index e78b84b..c32e5b9 100644
--- a/net/proxy_resolution/pac_library_unittest.cc
+++ b/net/proxy_resolution/pac_library_unittest.cc
@@ -284,6 +284,22 @@
     ADD_FAILURE() << "Called CreateProxyClientSocket()";
     return nullptr;
   }
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override {
+    ADD_FAILURE() << "Called CreateProxyClientSocket()";
+    return nullptr;
+  }
+
  private:
   std::vector<std::unique_ptr<MockUDPSocket>> udp_sockets_;
 
diff --git a/net/socket/client_socket_factory.cc b/net/socket/client_socket_factory.cc
index 62c1579..1b5f7cf 100644
--- a/net/socket/client_socket_factory.cc
+++ b/net/socket/client_socket_factory.cc
@@ -63,6 +63,24 @@
   }
 
   std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override {
+    return std::make_unique<HttpProxyClientSocket>(
+        std::move(stream_socket), user_agent, endpoint, proxy_server,
+        http_auth_controller, tunnel, using_spdy, negotiated_protocol,
+        proxy_delegate, is_https_proxy, traffic_annotation);
+  }
+
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
       std::unique_ptr<ClientSocketHandle> transport_socket,
       const std::string& user_agent,
       const HostPortPair& endpoint,
diff --git a/net/socket/client_socket_factory.h b/net/socket/client_socket_factory.h
index ad90eaa..6ac01e1 100644
--- a/net/socket/client_socket_factory.h
+++ b/net/socket/client_socket_factory.h
@@ -80,6 +80,20 @@
       ProxyDelegate* proxy_delegate,
       bool is_https_proxy,
       const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
+  // Newer version of the above method.
+  // TODO(mmenke): Remove above method in favor of this one.
+  virtual std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) = 0;
 
   // Returns the default ClientSocketFactory.
   static ClientSocketFactory* GetDefaultFactory();
diff --git a/net/socket/client_socket_pool_base_unittest.cc b/net/socket/client_socket_pool_base_unittest.cc
index e7380c8..e39f164 100644
--- a/net/socket/client_socket_pool_base_unittest.cc
+++ b/net/socket/client_socket_pool_base_unittest.cc
@@ -266,6 +266,22 @@
     return nullptr;
   }
 
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override {
+    NOTIMPLEMENTED();
+    return nullptr;
+  }
+
   void WaitForSignal(TestConnectJob* job) { waiting_jobs_.push_back(job); }
 
   void SignalJobs();
diff --git a/net/socket/fuzzed_socket_factory.cc b/net/socket/fuzzed_socket_factory.cc
index 5003a10..f9f8634 100644
--- a/net/socket/fuzzed_socket_factory.cc
+++ b/net/socket/fuzzed_socket_factory.cc
@@ -176,4 +176,20 @@
   return nullptr;
 }
 
+std::unique_ptr<ProxyClientSocket> FuzzedSocketFactory::CreateProxyClientSocket(
+    std::unique_ptr<StreamSocket> stream_socket,
+    const std::string& user_agent,
+    const HostPortPair& endpoint,
+    const ProxyServer& proxy_server,
+    HttpAuthController* http_auth_controller,
+    bool tunnel,
+    bool using_spdy,
+    NextProto negotiated_protocol,
+    ProxyDelegate* proxy_delegate,
+    bool is_https_proxy,
+    const NetworkTrafficAnnotationTag& traffic_annotation) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
 }  // namespace net
diff --git a/net/socket/fuzzed_socket_factory.h b/net/socket/fuzzed_socket_factory.h
index 695bbbcc..42f949e 100644
--- a/net/socket/fuzzed_socket_factory.h
+++ b/net/socket/fuzzed_socket_factory.h
@@ -6,6 +6,7 @@
 #define NET_SOCKET_FUZZED_SOCKET_FACTORY_H_
 
 #include <memory>
+#include <string>
 
 #include "base/macros.h"
 #include "net/socket/client_socket_factory.h"
@@ -71,6 +72,19 @@
       bool is_https_proxy,
       const NetworkTrafficAnnotationTag& traffic_annotation) override;
 
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override;
+
   // Sets whether Connect()ions on returned sockets can be asynchronously
   // delayed or outright fail. Defaults to true.
   void set_fuzz_connect_result(bool v) { fuzz_connect_result_ = v; }
diff --git a/net/socket/socket_test_util.cc b/net/socket/socket_test_util.cc
index 5260c894..c63941b0e 100644
--- a/net/socket/socket_test_util.cc
+++ b/net/socket/socket_test_util.cc
@@ -837,6 +837,31 @@
   }
 }
 
+std::unique_ptr<ProxyClientSocket>
+MockClientSocketFactory::CreateProxyClientSocket(
+    std::unique_ptr<StreamSocket> stream_socket,
+    const std::string& user_agent,
+    const HostPortPair& endpoint,
+    const ProxyServer& proxy_server,
+    HttpAuthController* http_auth_controller,
+    bool tunnel,
+    bool using_spdy,
+    NextProto negotiated_protocol,
+    ProxyDelegate* proxy_delegate,
+    bool is_https_proxy,
+    const NetworkTrafficAnnotationTag& traffic_annotation) {
+  if (use_mock_proxy_client_sockets_) {
+    ProxyClientSocketDataProvider* next_proxy_data = mock_proxy_data_.GetNext();
+    return std::make_unique<MockProxyClientSocket>(
+        std::move(stream_socket), http_auth_controller, next_proxy_data);
+  } else {
+    return GetDefaultFactory()->CreateProxyClientSocket(
+        std::move(stream_socket), user_agent, endpoint, proxy_server,
+        http_auth_controller, tunnel, using_spdy, negotiated_protocol,
+        proxy_delegate, is_https_proxy, traffic_annotation);
+  }
+}
+
 MockClientSocket::MockClientSocket(const NetLogWithSource& net_log)
     : connected_(false), net_log_(net_log), weak_factory_(this) {
   local_addr_ = IPEndPoint(IPAddress(192, 0, 2, 33), 123);
@@ -1277,11 +1302,25 @@
 }
 
 MockProxyClientSocket::MockProxyClientSocket(
-    std::unique_ptr<ClientSocketHandle> transport_socket,
+    std::unique_ptr<StreamSocket> stream_socket,
     HttpAuthController* auth_controller,
     ProxyClientSocketDataProvider* data)
-    : net_log_(transport_socket->socket()->NetLog()),
-      transport_(std::move(transport_socket)),
+    : net_log_(stream_socket->NetLog()),
+      stream_socket_(std::move(stream_socket)),
+      socket_(stream_socket_.get()),
+      data_(data),
+      auth_controller_(auth_controller),
+      weak_factory_(this) {
+  DCHECK(data_);
+}
+
+MockProxyClientSocket::MockProxyClientSocket(
+    std::unique_ptr<ClientSocketHandle> client_socket_handle,
+    HttpAuthController* auth_controller,
+    ProxyClientSocketDataProvider* data)
+    : net_log_(client_socket_handle->socket()->NetLog()),
+      client_socket_handle_(std::move(client_socket_handle)),
+      socket_(client_socket_handle_->socket()),
       data_(data),
       auth_controller_(auth_controller),
       weak_factory_(this) {
@@ -1315,13 +1354,13 @@
 int MockProxyClientSocket::Read(IOBuffer* buf,
                                 int buf_len,
                                 CompletionOnceCallback callback) {
-  return transport_->socket()->Read(buf, buf_len, std::move(callback));
+  return socket_->Read(buf, buf_len, std::move(callback));
 }
 
 int MockProxyClientSocket::ReadIfReady(IOBuffer* buf,
                                        int buf_len,
                                        CompletionOnceCallback callback) {
-  return transport_->socket()->ReadIfReady(buf, buf_len, std::move(callback));
+  return socket_->ReadIfReady(buf, buf_len, std::move(callback));
 }
 
 int MockProxyClientSocket::Write(
@@ -1329,12 +1368,11 @@
     int buf_len,
     CompletionOnceCallback callback,
     const NetworkTrafficAnnotationTag& traffic_annotation) {
-  return transport_->socket()->Write(buf, buf_len, std::move(callback),
-                                     traffic_annotation);
+  return socket_->Write(buf, buf_len, std::move(callback), traffic_annotation);
 }
 
 int MockProxyClientSocket::Connect(CompletionOnceCallback callback) {
-  DCHECK(transport_->socket()->IsConnected());
+  DCHECK(socket_->IsConnected());
   if (data_->connect.mode == ASYNC) {
     RunCallbackAsync(std::move(callback), data_->connect.result);
     return ERR_IO_PENDING;
@@ -1343,20 +1381,20 @@
 }
 
 void MockProxyClientSocket::Disconnect() {
-  if (transport_->socket() != NULL)
-    transport_->socket()->Disconnect();
+  if (socket_)
+    socket_->Disconnect();
 }
 
 bool MockProxyClientSocket::IsConnected() const {
-  return transport_->socket()->IsConnected();
+  return socket_->IsConnected();
 }
 
 bool MockProxyClientSocket::IsConnectedAndIdle() const {
-  return transport_->socket()->IsConnectedAndIdle();
+  return socket_->IsConnectedAndIdle();
 }
 
 bool MockProxyClientSocket::WasEverUsed() const {
-  return transport_->socket()->WasEverUsed();
+  return socket_->WasEverUsed();
 }
 
 int MockProxyClientSocket::GetLocalAddress(IPEndPoint* address) const {
@@ -1365,7 +1403,7 @@
 }
 
 int MockProxyClientSocket::GetPeerAddress(IPEndPoint* address) const {
-  return transport_->socket()->GetPeerAddress(address);
+  return socket_->GetPeerAddress(address);
 }
 
 bool MockProxyClientSocket::WasAlpnNegotiated() const {
@@ -1383,7 +1421,7 @@
 }
 
 void MockProxyClientSocket::ApplySocketTag(const SocketTag& tag) {
-  return transport_->socket()->ApplySocketTag(tag);
+  return socket_->ApplySocketTag(tag);
 }
 
 const NetLogWithSource& MockProxyClientSocket::NetLog() const {
diff --git a/net/socket/socket_test_util.h b/net/socket/socket_test_util.h
index 7f8d71e..7e5c52e7 100644
--- a/net/socket/socket_test_util.h
+++ b/net/socket/socket_test_util.h
@@ -643,6 +643,18 @@
       ProxyDelegate* proxy_delegate,
       bool is_https_proxy,
       const NetworkTrafficAnnotationTag& traffic_annotation) override;
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override;
   const std::vector<uint16_t>& udp_client_socket_ports() const {
     return udp_client_socket_ports_;
   }
@@ -817,7 +829,12 @@
 
 class MockProxyClientSocket : public AsyncSocket, public ProxyClientSocket {
  public:
-  MockProxyClientSocket(std::unique_ptr<ClientSocketHandle> transport_socket,
+  // TODO(mmenke): Remove this constructor.
+  MockProxyClientSocket(
+      std::unique_ptr<ClientSocketHandle> client_socket_handle,
+      HttpAuthController* auth_controller,
+      ProxyClientSocketDataProvider* data);
+  MockProxyClientSocket(std::unique_ptr<StreamSocket> stream_socket,
                         HttpAuthController* auth_controller,
                         ProxyClientSocketDataProvider* data);
   ~MockProxyClientSocket() override;
@@ -871,7 +888,9 @@
   void RunCallbackAsync(CompletionOnceCallback callback, int result);
 
   NetLogWithSource net_log_;
-  std::unique_ptr<ClientSocketHandle> transport_;
+  std::unique_ptr<ClientSocketHandle> client_socket_handle_;
+  std::unique_ptr<StreamSocket> stream_socket_;
+  StreamSocket* socket_;
   ProxyClientSocketDataProvider* data_;
   scoped_refptr<HttpAuthController> auth_controller_;
 
diff --git a/net/socket/socks5_client_socket_unittest.cc b/net/socket/socks5_client_socket_unittest.cc
index 5f44d95..f497b1a 100644
--- a/net/socket/socks5_client_socket_unittest.cc
+++ b/net/socket/socks5_client_socket_unittest.cc
@@ -17,7 +17,6 @@
 #include "net/base/address_list.h"
 #include "net/base/test_completion_callback.h"
 #include "net/base/winsock_init.h"
-#include "net/dns/mock_host_resolver.h"
 #include "net/log/net_log_event_type.h"
 #include "net/log/test_net_log.h"
 #include "net/log/test_net_log_entry.h"
@@ -67,7 +66,6 @@
   // (which |user_sock| is set to).
   StreamSocket* tcp_sock_;
   TestCompletionCallback callback_;
-  std::unique_ptr<MockHostResolver> host_resolver_;
   std::unique_ptr<SocketDataProvider> data_;
 
  private:
@@ -75,24 +73,15 @@
 };
 
 SOCKS5ClientSocketTest::SOCKS5ClientSocketTest()
-  : kNwPort(base::HostToNet16(80)),
-    host_resolver_(new MockHostResolver) {
-}
+    : kNwPort(base::HostToNet16(80)) {}
 
 // Set up platform before every test case
 void SOCKS5ClientSocketTest::SetUp() {
   PlatformTest::SetUp();
 
-  // Resolve the "localhost" AddressList used by the TCP connection to connect.
-  HostResolver::RequestInfo info(HostPortPair("www.socks-proxy.com", 1080));
-  TestCompletionCallback callback;
-  std::unique_ptr<HostResolver::Request> request;
-  int rv = host_resolver_->Resolve(info, DEFAULT_PRIORITY, &address_list_,
-                                   callback.callback(), &request,
-                                   NetLogWithSource());
-  ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
-  rv = callback.WaitForResult();
-  ASSERT_THAT(rv, IsOk());
+  // Create the "localhost" AddressList used by the TCP connection to connect.
+  address_list_ =
+      AddressList::CreateFromIPAddress(IPAddress::IPv4Localhost(), 1080);
 }
 
 std::unique_ptr<SOCKS5ClientSocket> SOCKS5ClientSocketTest::BuildMockSocket(
diff --git a/net/socket/transport_client_socket_pool_test_util.cc b/net/socket/transport_client_socket_pool_test_util.cc
index 6eef9bf..edb87f1 100644
--- a/net/socket/transport_client_socket_pool_test_util.cc
+++ b/net/socket/transport_client_socket_pool_test_util.cc
@@ -479,6 +479,23 @@
   return nullptr;
 }
 
+std::unique_ptr<ProxyClientSocket>
+MockTransportClientSocketFactory::CreateProxyClientSocket(
+    std::unique_ptr<StreamSocket> stream_socket,
+    const std::string& user_agent,
+    const HostPortPair& endpoint,
+    const ProxyServer& proxy_server,
+    HttpAuthController* http_auth_controller,
+    bool tunnel,
+    bool using_spdy,
+    NextProto negotiated_protocol,
+    ProxyDelegate* proxy_delegate,
+    bool is_https_proxy,
+    const NetworkTrafficAnnotationTag& traffic_annotation) {
+  NOTIMPLEMENTED();
+  return nullptr;
+}
+
 void MockTransportClientSocketFactory::set_client_socket_types(
     ClientSocketType* type_list,
     int num_types) {
diff --git a/net/socket/transport_client_socket_pool_test_util.h b/net/socket/transport_client_socket_pool_test_util.h
index 71b4a72..eeb7d03 100644
--- a/net/socket/transport_client_socket_pool_test_util.h
+++ b/net/socket/transport_client_socket_pool_test_util.h
@@ -111,6 +111,19 @@
       bool is_https_proxy,
       const NetworkTrafficAnnotationTag& traffic_annotation) override;
 
+  std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket(
+      std::unique_ptr<StreamSocket> stream_socket,
+      const std::string& user_agent,
+      const HostPortPair& endpoint,
+      const ProxyServer& proxy_server,
+      HttpAuthController* http_auth_controller,
+      bool tunnel,
+      bool using_spdy,
+      NextProto negotiated_protocol,
+      ProxyDelegate* proxy_delegate,
+      bool is_https_proxy,
+      const NetworkTrafficAnnotationTag& traffic_annotation) override;
+
   int allocation_count() const { return allocation_count_; }
 
   // Set the default ClientSocketType.
diff --git a/net/socket/transport_client_socket_unittest.cc b/net/socket/transport_client_socket_unittest.cc
index 37940565..9c98a1bf 100644
--- a/net/socket/transport_client_socket_unittest.cc
+++ b/net/socket/transport_client_socket_unittest.cc
@@ -13,7 +13,6 @@
 #include "net/base/ip_address.h"
 #include "net/base/net_errors.h"
 #include "net/base/test_completion_callback.h"
-#include "net/dns/mock_host_resolver.h"
 #include "net/log/net_log_event_type.h"
 #include "net/log/net_log_source.h"
 #include "net/log/net_log_with_source.h"
@@ -117,17 +116,8 @@
                        base::Bind(&TransportClientSocketTest::AcceptCallback,
                                   base::Unretained(this)));
 
-  AddressList addr;
-  // MockHostResolver resolves everything to 127.0.0.1.
-  std::unique_ptr<HostResolver> resolver(new MockHostResolver());
-  HostResolver::RequestInfo info(HostPortPair("localhost", listen_port_));
-  TestCompletionCallback callback;
-  std::unique_ptr<HostResolver::Request> request;
-  int rv = resolver->Resolve(info, DEFAULT_PRIORITY, &addr, callback.callback(),
-                             &request, NetLogWithSource());
-  CHECK_EQ(ERR_IO_PENDING, rv);
-  rv = callback.WaitForResult();
-  CHECK_EQ(rv, OK);
+  AddressList addr = AddressList::CreateFromIPAddress(
+      IPAddress::IPv4Localhost(), listen_port_);
   sock_ = socket_factory_->CreateTransportClientSocket(addr, NULL, &net_log_,
                                                        NetLogSource());
 }
diff --git a/net/third_party/quic/platform/impl/quic_flags_impl.cc b/net/third_party/quic/platform/impl/quic_flags_impl.cc
index 5e6962d..3fa45fc 100644
--- a/net/third_party/quic/platform/impl/quic_flags_impl.cc
+++ b/net/third_party/quic/platform/impl/quic_flags_impl.cc
@@ -5,6 +5,7 @@
 #include "net/third_party/quic/platform/impl/quic_flags_impl.h"
 
 #include <algorithm>
+#include <initializer_list>
 #include <iostream>
 #include <set>
 
@@ -153,9 +154,9 @@
 template <>
 bool TypedQuicFlagHelper<bool>::SetFlag(const std::string& s) const {
   static const base::NoDestructor<std::set<std::string>> kTrueValues(
-      {"", "1", "t", "true", "y", "yes"});
+      std::initializer_list<std::string>({"", "1", "t", "true", "y", "yes"}));
   static const base::NoDestructor<std::set<std::string>> kFalseValues(
-      {"0", "f", "false", "n", "no"});
+      std::initializer_list<std::string>({"0", "f", "false", "n", "no"}));
   if (kTrueValues->find(base::ToLowerASCII(s)) != kTrueValues->end()) {
     *flag_ = true;
     return true;
diff --git a/remoting/host/heartbeat_sender.cc b/remoting/host/heartbeat_sender.cc
index 41ce09e..b27db919 100644
--- a/remoting/host/heartbeat_sender.cc
+++ b/remoting/host/heartbeat_sender.cc
@@ -334,7 +334,7 @@
       new XmlElement(QName(kChromotingXmlNamespace, kHeartbeatQueryTag)));
   heartbeat->AddAttr(QName(kChromotingXmlNamespace, kHostIdAttr), host_id_);
   heartbeat->AddAttr(QName(kChromotingXmlNamespace, kSequenceIdAttr),
-                 base::IntToString(sequence_id_));
+                     base::NumberToString(sequence_id_));
   if (!host_offline_reason_.empty()) {
     heartbeat->AddAttr(
         QName(kChromotingXmlNamespace, kHostOfflineReasonAttr),
@@ -373,7 +373,7 @@
       new XmlElement(QName(kChromotingXmlNamespace, kHeartbeatSignatureTag)));
 
   std::string message = signal_strategy_->GetLocalAddress().jid() + ' ' +
-                        base::IntToString(sequence_id_);
+                        base::NumberToString(sequence_id_);
   std::string signature(host_key_pair_->SignMessage(message));
   signature_tag->AddText(signature);
 
diff --git a/remoting/host/heartbeat_sender_unittest.cc b/remoting/host/heartbeat_sender_unittest.cc
index ab8ec08..9550e3e2 100644
--- a/remoting/host/heartbeat_sender_unittest.cc
+++ b/remoting/host/heartbeat_sender_unittest.cc
@@ -154,14 +154,15 @@
     XmlElement* set_interval =
         new XmlElement(QName(kChromotingXmlNamespace, "set-interval"));
     result->AddElement(set_interval);
-    set_interval->AddText(base::IntToString(interval.InSeconds()));
+    set_interval->AddText(base::NumberToString(interval.InSeconds()));
   }
 
   if (expected_sequence_id > 0) {
     XmlElement* expected_sequence_id_tag =
         new XmlElement(QName(kChromotingXmlNamespace, "expected-sequence-id"));
     result->AddElement(expected_sequence_id_tag);
-    expected_sequence_id_tag->AddText(base::IntToString(expected_sequence_id));
+    expected_sequence_id_tag->AddText(
+        base::NumberToString(expected_sequence_id));
   }
 
   bot_signal_strategy_.SendStanza(std::move(response));
@@ -216,7 +217,7 @@
 
   ASSERT_EQ(bot_signal_strategy_.received_messages().size(), 2U);
   ValidateHeartbeatStanza(bot_signal_strategy_.received_messages()[1].get(),
-                          base::IntToString(kExpectedSequenceId).c_str(),
+                          base::NumberToString(kExpectedSequenceId).c_str(),
                           std::string());
 
   signal_strategy_.Disconnect();
diff --git a/remoting/host/logging_mac.cc b/remoting/host/logging_mac.cc
index 39e007d..d153661 100644
--- a/remoting/host/logging_mac.cc
+++ b/remoting/host/logging_mac.cc
@@ -67,12 +67,12 @@
     return false;
 
   if (asl_set(asl_message.get(), ASL_KEY_LEVEL,
-              base::IntToString(level).c_str()) != 0)
+              base::NumberToString(level).c_str()) != 0)
     return false;
 
   // Restrict read access to the message to root and the current user.
   if (asl_set(asl_message.get(), ASL_KEY_READ_UID,
-              base::IntToString(geteuid()).c_str()) != 0)
+              base::NumberToString(geteuid()).c_str()) != 0)
     return false;
 
   if (asl_set(asl_message.get(), ASL_KEY_MSG,
diff --git a/remoting/host/register_support_host_request.cc b/remoting/host/register_support_host_request.cc
index 34944cf..4aed339c 100644
--- a/remoting/host/register_support_host_request.cc
+++ b/remoting/host/register_support_host_request.cc
@@ -142,7 +142,7 @@
       new XmlElement(QName(kChromotingXmlNamespace, kSignatureTag)));
 
   int64_t time = static_cast<int64_t>(base::Time::Now().ToDoubleT());
-  std::string time_str(base::Int64ToString(time));
+  std::string time_str(base::NumberToString(time));
   signature_tag->AddAttr(
       QName(kChromotingXmlNamespace, kSignatureTimeAttr), time_str);
 
diff --git a/remoting/ios/facade/host_list_service.mm b/remoting/ios/facade/host_list_service.mm
index 8feb8e6..47c8753 100644
--- a/remoting/ios/facade/host_list_service.mm
+++ b/remoting/ios/facade/host_list_service.mm
@@ -53,7 +53,7 @@
       return l10n_util::GetStringUTF8(IDS_ERROR_NETWORK_ERROR);
     default:
       return l10n_util::GetStringFUTF8(IDS_SERVER_COMMUNICATION_ERROR,
-                                       base::IntToString16(error_code));
+                                       base::NumberToString16(error_code));
   }
 }
 
diff --git a/remoting/protocol/content_description.cc b/remoting/protocol/content_description.cc
index b7d2a60a..32af610 100644
--- a/remoting/protocol/content_description.cc
+++ b/remoting/protocol/content_description.cc
@@ -71,7 +71,7 @@
 
   if (config.transport != ChannelConfig::TRANSPORT_NONE) {
     result->AddAttr(QName(kDefaultNs, kVersionAttr),
-                    base::IntToString(config.version));
+                    base::NumberToString(config.version));
 
     if (config.codec != ChannelConfig::CODEC_UNDEFINED) {
       result->AddAttr(QName(kDefaultNs, kCodecAttr),
diff --git a/remoting/protocol/fake_authenticator.cc b/remoting/protocol/fake_authenticator.cc
index 696a4fd..abac8a7 100644
--- a/remoting/protocol/fake_authenticator.cc
+++ b/remoting/protocol/fake_authenticator.cc
@@ -167,7 +167,7 @@
   EXPECT_EQ(WAITING_MESSAGE, state());
   std::string id =
       message->TextNamed(jingle_xmpp::QName(kChromotingXmlNamespace, "id"));
-  EXPECT_EQ(id, base::IntToString(messages_));
+  EXPECT_EQ(id, base::NumberToString(messages_));
 
   // On the client receive the key in the last message.
   if (type_ == CLIENT && messages_ == config_.round_trips * 2 - 1) {
@@ -197,7 +197,7 @@
       jingle_xmpp::QName(kChromotingXmlNamespace, "authentication")));
   jingle_xmpp::XmlElement* id = new jingle_xmpp::XmlElement(
       jingle_xmpp::QName(kChromotingXmlNamespace, "id"));
-  id->AddText(base::IntToString(messages_));
+  id->AddText(base::NumberToString(messages_));
   result->AddElement(id);
 
   // Send local id in the first outgoing message.
diff --git a/remoting/protocol/jingle_messages.cc b/remoting/protocol/jingle_messages.cc
index f0ecfd2..75526f2f 100644
--- a/remoting/protocol/jingle_messages.cc
+++ b/remoting/protocol/jingle_messages.cc
@@ -134,14 +134,14 @@
   result->SetAttr(QName(kEmptyNamespace, "address"),
                   candidate.candidate.address().ipaddr().ToString());
   result->SetAttr(QName(kEmptyNamespace, "port"),
-                  base::UintToString(candidate.candidate.address().port()));
+                  base::NumberToString(candidate.candidate.address().port()));
   result->SetAttr(QName(kEmptyNamespace, "type"), candidate.candidate.type());
   result->SetAttr(QName(kEmptyNamespace, "protocol"),
                   candidate.candidate.protocol());
   result->SetAttr(QName(kEmptyNamespace, "priority"),
-                  base::UintToString(candidate.candidate.priority()));
+                  base::NumberToString(candidate.candidate.priority()));
   result->SetAttr(QName(kEmptyNamespace, "generation"),
-                  base::UintToString(candidate.candidate.generation()));
+                  base::NumberToString(candidate.candidate.generation()));
   return result;
 }
 
diff --git a/remoting/protocol/jingle_session.cc b/remoting/protocol/jingle_session.cc
index 70ce34ad..6e8c769 100644
--- a/remoting/protocol/jingle_session.cc
+++ b/remoting/protocol/jingle_session.cc
@@ -818,7 +818,7 @@
 }
 
 std::string JingleSession::GetNextOutgoingId() {
-  return outgoing_id_prefix_ + "_" + base::IntToString(++next_outgoing_id_);
+  return outgoing_id_prefix_ + "_" + base::NumberToString(++next_outgoing_id_);
 }
 
 }  // namespace protocol
diff --git a/remoting/protocol/jingle_session_unittest.cc b/remoting/protocol/jingle_session_unittest.cc
index 1c8b2b1..280e4a3 100644
--- a/remoting/protocol/jingle_session_unittest.cc
+++ b/remoting/protocol/jingle_session_unittest.cc
@@ -111,7 +111,7 @@
  public:
    std::unique_ptr<jingle_xmpp::XmlElement> GetNextMessage() override {
      std::string tag_name = "test-tag-";
-     tag_name += base::IntToString(outgoing_messages_.size());
+     tag_name += base::NumberToString(outgoing_messages_.size());
      std::unique_ptr<jingle_xmpp::XmlElement> new_message(new jingle_xmpp::XmlElement(
          jingle_xmpp::QName("test-namespace", tag_name)));
      outgoing_messages_.push_back(*new_message);
diff --git a/remoting/protocol/message_decoder_unittest.cc b/remoting/protocol/message_decoder_unittest.cc
index f905ffc..ef8417a 100644
--- a/remoting/protocol/message_decoder_unittest.cc
+++ b/remoting/protocol/message_decoder_unittest.cc
@@ -66,7 +66,7 @@
   // read pattern.
   std::list<std::unique_ptr<EventMessage>> message_list;
   for (int pos = 0; pos < size;) {
-    SCOPED_TRACE("Input position: " + base::IntToString(pos));
+    SCOPED_TRACE("Input position: " + base::NumberToString(pos));
 
     // First generate the amount to feed the decoder.
     int read = std::min(size - pos, read_sequence[pos % sequence_size]);
@@ -94,7 +94,7 @@
 
   unsigned int index = 0;
   for (const auto& message : message_list) {
-    SCOPED_TRACE("Message " + base::UintToString(index));
+    SCOPED_TRACE("Message " + base::NumberToString(index));
 
     // Partial update stream.
     EXPECT_TRUE(message->has_key_event());
diff --git a/remoting/protocol/webrtc_transport.cc b/remoting/protocol/webrtc_transport.cc
index bea943a..24df24a 100644
--- a/remoting/protocol/webrtc_transport.cc
+++ b/remoting/protocol/webrtc_transport.cc
@@ -743,8 +743,9 @@
   candidate_element->SetBodyText(candidate_str);
   candidate_element->SetAttr(QName(std::string(), "sdpMid"),
                              candidate->sdp_mid());
-  candidate_element->SetAttr(QName(std::string(), "sdpMLineIndex"),
-                             base::IntToString(candidate->sdp_mline_index()));
+  candidate_element->SetAttr(
+      QName(std::string(), "sdpMLineIndex"),
+      base::NumberToString(candidate->sdp_mline_index()));
 
   EnsurePendingTransportInfoMessage();
   pending_transport_info_message_->AddElement(candidate_element.release());
diff --git a/remoting/signaling/fake_signal_strategy.cc b/remoting/signaling/fake_signal_strategy.cc
index 85c75e4..91c4304 100644
--- a/remoting/signaling/fake_signal_strategy.cc
+++ b/remoting/signaling/fake_signal_strategy.cc
@@ -121,7 +121,7 @@
 
 std::string FakeSignalStrategy::GetNextId() {
   ++last_id_;
-  return base::IntToString(last_id_);
+  return base::NumberToString(last_id_);
 }
 
 // static
diff --git a/services/content/BUILD.gn b/services/content/BUILD.gn
index e37d84a..5ed7974 100644
--- a/services/content/BUILD.gn
+++ b/services/content/BUILD.gn
@@ -4,7 +4,6 @@
 
 import("//build/config/ui.gni")
 import("//services/content/public/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 source_set("impl") {
   visibility = [
@@ -76,8 +75,3 @@
     "//url",
   ]
 }
-
-service_manifest("manifest") {
-  name = "content"
-  source = "manifest.json"
-}
diff --git a/services/content/OWNERS b/services/content/OWNERS
index 300133b..eb504e3 100644
--- a/services/content/OWNERS
+++ b/services/content/OWNERS
@@ -2,6 +2,3 @@
 clamy@chromium.org
 jam@chromium.org
 rockot@google.com
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/services/content/manifest.json b/services/content/manifest.json
deleted file mode 100644
index c47c4be..0000000
--- a/services/content/manifest.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-  "name": "content",
-  "display_name": "Content Service",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        // The |navigation| capability allows a service to acquire embeddable,
-        // navigable contents. for now, access to this capability should be
-        // restricted only to services which are at least as trusted as the
-        // Chrome browser process (e.g., Ash).
-        "navigation": [
-          "content.mojom.NavigableContentsFactory"
-        ]
-      }
-    }
-  }
-}
diff --git a/services/content/public/cpp/BUILD.gn b/services/content/public/cpp/BUILD.gn
index 6559e3e..70d3881 100644
--- a/services/content/public/cpp/BUILD.gn
+++ b/services/content/public/cpp/BUILD.gn
@@ -56,3 +56,16 @@
     deps += [ "//ui/aura" ]
   }
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/content/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/content/public/cpp/OWNERS b/services/content/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/services/content/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/content/public/cpp/manifest.cc b/services/content/public/cpp/manifest.cc
new file mode 100644
index 0000000..e4717d03
--- /dev/null
+++ b/services/content/public/cpp/manifest.cc
@@ -0,0 +1,26 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/content/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/content/public/mojom/constants.mojom.h"
+#include "services/content/public/mojom/navigable_contents_factory.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace content {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Content Service")
+          .ExposeCapability("navigation",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::NavigableContentsFactory>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace content
diff --git a/services/content/public/cpp/manifest.h b/services/content/public/cpp/manifest.h
new file mode 100644
index 0000000..cad48525
--- /dev/null
+++ b/services/content/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_CONTENT_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_CONTENT_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace content {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace content
+
+#endif  // SERVICES_CONTENT_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/content/simple_browser/BUILD.gn b/services/content/simple_browser/BUILD.gn
index 6ca576e6..1e0e96ae 100644
--- a/services/content/simple_browser/BUILD.gn
+++ b/services/content/simple_browser/BUILD.gn
@@ -4,7 +4,6 @@
 
 import("//build/config/ui.gni")
 import("//services/content/public/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 component("simple_browser") {
   public = [
@@ -51,8 +50,3 @@
     ]
   }
 }
-
-service_manifest("manifest") {
-  name = "simple_browser"
-  source = "manifest.json"
-}
diff --git a/services/content/simple_browser/OWNERS b/services/content/simple_browser/OWNERS
index 59dfd4b3..e69de29 100644
--- a/services/content/simple_browser/OWNERS
+++ b/services/content/simple_browser/OWNERS
@@ -1,2 +0,0 @@
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/services/content/simple_browser/manifest.json b/services/content/simple_browser/manifest.json
deleted file mode 100644
index 44ca599..0000000
--- a/services/content/simple_browser/manifest.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
-  "name": "simple_browser",
-  "display_name": "Simple Browser",
-  "sandbox_type": "utility",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        // Dummy capability so someone can start/connect.
-        "app": []
-      },
-      "requires": {
-        "content": [ "navigation" ],
-        "font_service": [ "font_service" ],
-        "ui": [ "app" ]
-      }
-    }
-  }
-}
diff --git a/services/content/simple_browser/public/cpp/BUILD.gn b/services/content/simple_browser/public/cpp/BUILD.gn
new file mode 100644
index 0000000..008d5c4
--- /dev/null
+++ b/services/content/simple_browser/public/cpp/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/content/simple_browser/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/content/simple_browser/public/cpp/OWNERS b/services/content/simple_browser/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/services/content/simple_browser/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/content/simple_browser/public/cpp/manifest.cc b/services/content/simple_browser/public/cpp/manifest.cc
new file mode 100644
index 0000000..05301ff
--- /dev/null
+++ b/services/content/simple_browser/public/cpp/manifest.cc
@@ -0,0 +1,29 @@
+// 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 "services/content/simple_browser/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/content/simple_browser/public/mojom/constants.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace simple_browser {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Simple Browser")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("utility")
+                           .Build())
+          .ExposeCapability("app", {})
+          .RequireCapability("content", "navigation")
+          .RequireCapability("font_service", "font_service")
+          .RequireCapability("ui", "app")
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace simple_browser
diff --git a/services/content/simple_browser/public/cpp/manifest.h b/services/content/simple_browser/public/cpp/manifest.h
new file mode 100644
index 0000000..ff91acab
--- /dev/null
+++ b/services/content/simple_browser/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_CONTENT_SIMPLE_BROWSER_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_CONTENT_SIMPLE_BROWSER_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace simple_browser {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace simple_browser
+
+#endif  // SERVICES_CONTENT_SIMPLE_BROWSER_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/data_decoder/BUILD.gn b/services/data_decoder/BUILD.gn
index 4c96e1c..582bd7f 100644
--- a/services/data_decoder/BUILD.gn
+++ b/services/data_decoder/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
 import("//testing/libfuzzer/fuzzer_test.gni")
 
 source_set("lib") {
@@ -70,11 +69,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "data_decoder"
-  source = "manifest.json"
-}
-
 fuzzer_test("xml_parser_fuzzer") {
   sources = [
     "xml_parser_fuzzer.cc",
diff --git a/services/data_decoder/OWNERS b/services/data_decoder/OWNERS
index 804dc4b..78112f0 100644
--- a/services/data_decoder/OWNERS
+++ b/services/data_decoder/OWNERS
@@ -1,5 +1,3 @@
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 
 jcivelli@chromium.org
 rsesek@chromium.org
diff --git a/services/data_decoder/manifest.json b/services/data_decoder/manifest.json
deleted file mode 100644
index 70d5388..0000000
--- a/services/data_decoder/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "data_decoder",
-  "display_name": "Data Decoder Service",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "image_decoder": [ "data_decoder.mojom.ImageDecoder" ],
-        "json_parser": [ "data_decoder.mojom.JsonParser" ],
-        "xml_parser": [ "data_decoder.mojom.XmlParser" ]
-      }
-    }
-  }
-}
diff --git a/services/data_decoder/public/cpp/BUILD.gn b/services/data_decoder/public/cpp/BUILD.gn
index d5a81fd..11a5c050 100644
--- a/services/data_decoder/public/cpp/BUILD.gn
+++ b/services/data_decoder/public/cpp/BUILD.gn
@@ -55,3 +55,16 @@
     "//services/service_manager/public/cpp/test:test_support",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/data_decoder/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/data_decoder/public/cpp/OWNERS b/services/data_decoder/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/services/data_decoder/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/data_decoder/public/cpp/manifest.cc b/services/data_decoder/public/cpp/manifest.cc
new file mode 100644
index 0000000..0aa50bf8
--- /dev/null
+++ b/services/data_decoder/public/cpp/manifest.cc
@@ -0,0 +1,39 @@
+// 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 "services/data_decoder/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/data_decoder/public/mojom/constants.mojom.h"
+#include "services/data_decoder/public/mojom/image_decoder.mojom.h"
+#include "services/data_decoder/public/mojom/json_parser.mojom.h"
+#include "services/data_decoder/public/mojom/xml_parser.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace data_decoder {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Data Decoder Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability(
+              "image_decoder",
+              service_manager::Manifest::InterfaceList<mojom::ImageDecoder>())
+          .ExposeCapability(
+              "json_parser",
+              service_manager::Manifest::InterfaceList<mojom::JsonParser>())
+          .ExposeCapability(
+              "xml_parser",
+              service_manager::Manifest::InterfaceList<mojom::XmlParser>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace data_decoder
diff --git a/services/data_decoder/public/cpp/manifest.h b/services/data_decoder/public/cpp/manifest.h
new file mode 100644
index 0000000..df82d1e1
--- /dev/null
+++ b/services/data_decoder/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_DATA_DECODER_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_DATA_DECODER_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace data_decoder {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace data_decoder
+
+#endif  // SERVICES_DATA_DECODER_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/device/BUILD.gn b/services/device/BUILD.gn
index 3aa68b4..1e28c33 100644
--- a/services/device/BUILD.gn
+++ b/services/device/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//build/config/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 if (is_android) {
   import("//build/config/android/rules.gni")
@@ -222,11 +221,6 @@
   }
 }
 
-service_manifest("manifest") {
-  name = "device"
-  source = "manifest.json"
-}
-
 source_set("test_support") {
   testonly = true
 
diff --git a/services/device/OWNERS b/services/device/OWNERS
index d1e979e0..84a9943 100644
--- a/services/device/OWNERS
+++ b/services/device/OWNERS
@@ -5,6 +5,3 @@
 reillyg@chromium.org
 rockot@google.com
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
-
diff --git a/services/device/bluetooth/bluetooth_system.cc b/services/device/bluetooth/bluetooth_system.cc
index a671dd3b..71cb184 100644
--- a/services/device/bluetooth/bluetooth_system.cc
+++ b/services/device/bluetooth/bluetooth_system.cc
@@ -140,9 +140,11 @@
   switch (state_) {
     case State::kUnsupported:
     case State::kUnavailable:
-      std::move(callback).Run(SetPoweredResult::kBluetoothUnavailable);
+      std::move(callback).Run(SetPoweredResult::kFailedBluetoothUnavailable);
       return;
     case State::kTransitioning:
+      std::move(callback).Run(SetPoweredResult::kFailedInProgress);
+      return;
     case State::kPoweredOff:
     case State::kPoweredOn:
       break;
@@ -153,12 +155,9 @@
     return;
   }
 
-  // Update the BluetoothSystem state to kTransitioning if a previous call to
-  // SetPowered() has not done so already.
-  if (state_ != State::kTransitioning) {
-    state_ = State::kTransitioning;
-    client_ptr_->OnStateChanged(state_);
-  }
+  DCHECK_NE(state_, State::kTransitioning);
+  state_ = State::kTransitioning;
+  client_ptr_->OnStateChanged(state_);
 
   GetBluetoothAdapterClient()
       ->GetProperties(active_adapter_.value())
@@ -193,7 +192,7 @@
     case State::kUnavailable:
     case State::kPoweredOff:
     case State::kTransitioning:
-      std::move(callback).Run(StartScanResult::kBluetoothUnavailable);
+      std::move(callback).Run(StartScanResult::kFailedBluetoothUnavailable);
       return;
     case State::kPoweredOn:
       break;
@@ -211,7 +210,7 @@
     case State::kUnavailable:
     case State::kPoweredOff:
     case State::kTransitioning:
-      std::move(callback).Run(StopScanResult::kBluetoothUnavailable);
+      std::move(callback).Run(StopScanResult::kFailedBluetoothUnavailable);
       return;
     case State::kPoweredOn:
       break;
diff --git a/services/device/bluetooth/bluetooth_system_unittest.cc b/services/device/bluetooth/bluetooth_system_unittest.cc
index def87de..b52a5ac 100644
--- a/services/device/bluetooth/bluetooth_system_unittest.cc
+++ b/services/device/bluetooth/bluetooth_system_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "services/device/bluetooth/bluetooth_system.h"
 
+#include <deque>
 #include <map>
 #include <memory>
 #include <string>
@@ -119,7 +120,7 @@
           callback.Run(GetValueAndReset(&next_set_powered_response_));
           return;
         }
-        set_property_callbacks_.push_back(callback);
+        set_powered_callbacks_.push_back(callback);
       } else {
         NOTIMPLEMENTED();
       }
@@ -129,10 +130,10 @@
     base::Optional<bool> next_set_powered_response_;
     base::Optional<bool> last_set_powered_value_;
 
-    // Saved `Set()` callbacks. If there is no next response set for a `Set()`
-    // call, then the callback is saved here. TestBluetoothAdapterClient
+    // Saved `Set('powered')` callbacks. If there is no next response set for a
+    // `Set()` call, then the callback is saved here. TestBluetoothAdapterClient
     // runs all these callbacks after the adapter is removed.
-    std::vector<base::OnceCallback<void(bool)>> set_property_callbacks_;
+    std::deque<base::OnceCallback<void(bool)>> set_powered_callbacks_;
   };
 
   TestBluetoothAdapterClient() = default;
@@ -206,8 +207,8 @@
     DCHECK_EQ(1u, removed);
 
     // After the adapter is removed, any pending Set calls get run with `false`.
-    for (auto& set_property_callback : properties->set_property_callbacks_) {
-      std::move(set_property_callback).Run(false);
+    for (auto& set_powered_callback : properties->set_powered_callbacks_) {
+      std::move(set_powered_callback).Run(false);
     }
   }
 
@@ -248,6 +249,17 @@
         ->GetLastSetPoweredValue();
   }
 
+  void SimulateSetPoweredCompleted(
+      bool success,
+      const std::string& object_path_str = kDefaultAdapterObjectPathStr) {
+    auto& callbacks = GetProperties(dbus::ObjectPath(object_path_str))
+                          ->set_powered_callbacks_;
+    auto callback = std::move(callbacks.front());
+    callbacks.pop_front();
+
+    std::move(callback).Run(success);
+  }
+
   // Simulates adapter at |object_path_str| changing its discovering state to
   // |powered|.
   void SimulateAdapterDiscoveringStateChanged(
@@ -986,10 +998,12 @@
 TEST_F(BluetoothSystemTest, SetPowered_NoAdapter) {
   auto system = CreateBluetoothSystem();
 
-  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kBluetoothUnavailable,
-            SetPoweredAndWait(system, false));
-  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kBluetoothUnavailable,
-            SetPoweredAndWait(system, false));
+  EXPECT_EQ(
+      mojom::BluetoothSystem::SetPoweredResult::kFailedBluetoothUnavailable,
+      SetPoweredAndWait(system, false));
+  EXPECT_EQ(
+      mojom::BluetoothSystem::SetPoweredResult::kFailedBluetoothUnavailable,
+      SetPoweredAndWait(system, false));
 }
 
 // Tests setting powered to "Off" when the adapter is "Off" already.
@@ -1197,6 +1211,216 @@
   EXPECT_TRUE(on_state_changed_states_.empty());
 }
 
+// Tests power off call with pending power off call.
+TEST_F(BluetoothSystemTest, SetPoweredOff_PendingSetPoweredOff) {
+  test_bluetooth_adapter_client_->SimulatePoweredOnAdapter();
+
+  auto system = CreateBluetoothSystem();
+  ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOn, GetStateAndWait(system));
+
+  // Start powering off BT and wait for the state to change to
+  // kTransitioning.
+  base::RunLoop run_loop;
+  base::Optional<mojom::BluetoothSystem::SetPoweredResult>
+      set_powered_off_result;
+  system->SetPowered(false,
+                     base::BindLambdaForTesting(
+                         [&](mojom::BluetoothSystem::SetPoweredResult r) {
+                           set_powered_off_result = r;
+                           run_loop.Quit();
+                         }));
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}),
+            on_state_changed_states_);
+  EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_FALSE(test_bluetooth_adapter_client_->GetLastSetPoweredValue());
+
+  ResetResults();
+  test_bluetooth_adapter_client_->ResetCallCount();
+
+  // Try to power off BT; should fail with kInProgress.
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress,
+            SetPoweredAndWait(system, false));
+
+  EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector(), on_state_changed_states_);
+
+  ResetResults();
+
+  // Finish initial call to power off BT.
+  test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true);
+  test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false);
+  run_loop.Run();
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}),
+            on_state_changed_states_);
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess,
+            set_powered_off_result.value());
+}
+
+// Tests power off call with pending power on call.
+TEST_F(BluetoothSystemTest, SetPoweredOff_PendingSetPoweredOn) {
+  test_bluetooth_adapter_client_->SimulateAdapterAdded();
+
+  auto system = CreateBluetoothSystem();
+  ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOff,
+            GetStateAndWait(system));
+
+  // Start powering on BT and wait for the state to change to
+  // kTransitioning.
+  base::RunLoop run_loop;
+  base::Optional<mojom::BluetoothSystem::SetPoweredResult>
+      set_powered_on_result;
+  system->SetPowered(true, base::BindLambdaForTesting(
+                               [&](mojom::BluetoothSystem::SetPoweredResult r) {
+                                 set_powered_on_result = r;
+                                 run_loop.Quit();
+                               }));
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}),
+            on_state_changed_states_);
+  EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_TRUE(test_bluetooth_adapter_client_->GetLastSetPoweredValue());
+
+  ResetResults();
+  test_bluetooth_adapter_client_->ResetCallCount();
+
+  // Try to power off BT; should fail with kInProgress.
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress,
+            SetPoweredAndWait(system, false));
+
+  EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector(), on_state_changed_states_);
+
+  ResetResults();
+
+  // Finish initial call to power on BT.
+  test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true);
+  test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true);
+  run_loop.Run();
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}),
+            on_state_changed_states_);
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess,
+            set_powered_on_result.value());
+}
+
+// Tests power on call with pending power off call.
+TEST_F(BluetoothSystemTest, SetPoweredOn_PendingSetPoweredOff) {
+  test_bluetooth_adapter_client_->SimulatePoweredOnAdapter();
+
+  auto system = CreateBluetoothSystem();
+  ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOn, GetStateAndWait(system));
+
+  // Start powering off BT and wait for the state to change to
+  // kTransitioning.
+  base::RunLoop run_loop;
+  base::Optional<mojom::BluetoothSystem::SetPoweredResult>
+      set_powered_off_result;
+  system->SetPowered(false,
+                     base::BindLambdaForTesting(
+                         [&](mojom::BluetoothSystem::SetPoweredResult r) {
+                           set_powered_off_result = r;
+                           run_loop.Quit();
+                         }));
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}),
+            on_state_changed_states_);
+  EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_FALSE(test_bluetooth_adapter_client_->GetLastSetPoweredValue());
+
+  ResetResults();
+  test_bluetooth_adapter_client_->ResetCallCount();
+
+  // Try to power on BT; should fail with kInProgress.
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress,
+            SetPoweredAndWait(system, true));
+
+  EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector(), on_state_changed_states_);
+
+  ResetResults();
+
+  // Finish initial call to power off BT.
+  test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true);
+  test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(false);
+  run_loop.Run();
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOff,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOff}),
+            on_state_changed_states_);
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess,
+            set_powered_off_result.value());
+}
+
+// Tests power on call with pending power on call.
+TEST_F(BluetoothSystemTest, SetPoweredOn_PendingSetPoweredOn) {
+  test_bluetooth_adapter_client_->SimulateAdapterAdded();
+
+  auto system = CreateBluetoothSystem();
+  ASSERT_EQ(mojom::BluetoothSystem::State::kPoweredOff,
+            GetStateAndWait(system));
+
+  // Start powering on BT and wait for the state to change to
+  // kTransitioning.
+  base::RunLoop run_loop;
+  base::Optional<mojom::BluetoothSystem::SetPoweredResult>
+      set_powered_on_result;
+  system->SetPowered(true, base::BindLambdaForTesting(
+                               [&](mojom::BluetoothSystem::SetPoweredResult r) {
+                                 set_powered_on_result = r;
+                                 run_loop.Quit();
+                               }));
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kTransitioning}),
+            on_state_changed_states_);
+  EXPECT_EQ(1u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_TRUE(test_bluetooth_adapter_client_->GetLastSetPoweredValue());
+
+  ResetResults();
+  test_bluetooth_adapter_client_->ResetCallCount();
+
+  // Try to power on BT; should fail with kInProgress.
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kFailedInProgress,
+            SetPoweredAndWait(system, true));
+
+  EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetSetPoweredCallCount());
+  EXPECT_EQ(mojom::BluetoothSystem::State::kTransitioning,
+            GetStateAndWait(system));
+  EXPECT_EQ(StateVector(), on_state_changed_states_);
+
+  ResetResults();
+
+  // Finish initial call to power on BT.
+  test_bluetooth_adapter_client_->SimulateSetPoweredCompleted(true);
+  test_bluetooth_adapter_client_->SimulateAdapterPowerStateChanged(true);
+  run_loop.Run();
+
+  EXPECT_EQ(mojom::BluetoothSystem::State::kPoweredOn, GetStateAndWait(system));
+  EXPECT_EQ(StateVector({mojom::BluetoothSystem::State::kPoweredOn}),
+            on_state_changed_states_);
+  EXPECT_EQ(mojom::BluetoothSystem::SetPoweredResult::kSuccess,
+            set_powered_on_result.value());
+}
+
 // Tests scan state is kNotScanning when there is no adapter.
 TEST_F(BluetoothSystemTest, ScanState_NoAdapter) {
   auto system = CreateBluetoothSystem();
@@ -1343,8 +1567,9 @@
 TEST_F(BluetoothSystemTest, StartScan_NoAdapter) {
   auto system = CreateBluetoothSystem();
 
-  EXPECT_EQ(mojom::BluetoothSystem::StartScanResult::kBluetoothUnavailable,
-            StartScanAndWait(system));
+  EXPECT_EQ(
+      mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable,
+      StartScanAndWait(system));
 }
 
 // Tests that StartScan fails if the adapter is "Off".
@@ -1354,8 +1579,9 @@
 
   auto system = CreateBluetoothSystem();
 
-  EXPECT_EQ(mojom::BluetoothSystem::StartScanResult::kBluetoothUnavailable,
-            StartScanAndWait(system));
+  EXPECT_EQ(
+      mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable,
+      StartScanAndWait(system));
   EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount());
 }
 
@@ -1422,8 +1648,9 @@
   ResetResults();
 
   // Start scan should fail without sending the command to the adapter.
-  EXPECT_EQ(mojom::BluetoothSystem::StartScanResult::kBluetoothUnavailable,
-            StartScanAndWait(system));
+  EXPECT_EQ(
+      mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable,
+      StartScanAndWait(system));
   EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount());
   EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning,
             GetScanStateAndWait(system));
@@ -1452,8 +1679,9 @@
   ResetResults();
 
   // Start scan should fail without sending the command to the adapter.
-  EXPECT_EQ(mojom::BluetoothSystem::StartScanResult::kBluetoothUnavailable,
-            StartScanAndWait(system));
+  EXPECT_EQ(
+      mojom::BluetoothSystem::StartScanResult::kFailedBluetoothUnavailable,
+      StartScanAndWait(system));
   EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStartDiscoveryCallCount());
   EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning,
             GetScanStateAndWait(system));
@@ -1472,7 +1700,7 @@
 TEST_F(BluetoothSystemTest, StopScan_NoAdapter) {
   auto system = CreateBluetoothSystem();
 
-  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kBluetoothUnavailable,
+  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable,
             StopScanAndWait(system));
 }
 
@@ -1483,7 +1711,7 @@
 
   auto system = CreateBluetoothSystem();
 
-  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kBluetoothUnavailable,
+  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable,
             StopScanAndWait(system));
   EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount());
 }
@@ -1562,7 +1790,7 @@
   ResetResults();
 
   // Stop scan should fail without sending the command to the adapter.
-  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kBluetoothUnavailable,
+  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable,
             StopScanAndWait(system));
   EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount());
   EXPECT_EQ(mojom::BluetoothSystem::ScanState::kNotScanning,
@@ -1599,7 +1827,7 @@
   ResetResults();
 
   // Stop scan should fail without sending the command to the adapter.
-  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kBluetoothUnavailable,
+  EXPECT_EQ(mojom::BluetoothSystem::StopScanResult::kFailedBluetoothUnavailable,
             StopScanAndWait(system));
   EXPECT_EQ(0u, test_bluetooth_adapter_client_->GetStopDiscoveryCallCount());
   EXPECT_EQ(mojom::BluetoothSystem::ScanState::kScanning,
diff --git a/services/device/manifest.json b/services/device/manifest.json
deleted file mode 100644
index 324c5cbc..0000000
--- a/services/device/manifest.json
+++ /dev/null
@@ -1,33 +0,0 @@
-{
-  "name": "device",
-  "display_name": "Device Service",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "device:battery_monitor": [ "device.mojom.BatteryMonitor" ],
-        "device:bluetooth_system": [ "device.mojom.BluetoothSystemFactory" ],
-        "device:fingerprint": [ "device.mojom.Fingerprint" ],
-        "device:generic_sensor": [ "device.mojom.SensorProvider" ],
-        "device:geolocation": [ "device.mojom.GeolocationContext" ],
-        "device:geolocation_config": [ "device.mojom.GeolocationConfig" ],
-        "device:geolocation_control": [ "device.mojom.GeolocationControl" ],
-        "device:hid": [ "device.mojom.HidManager" ],
-        "device:input_service": [ "device.mojom.InputDeviceManager" ],
-        "device:ip_geolocator": [ "device.mojom.PublicIpAddressGeolocationProvider" ],
-        "device:mtp": [ "device.mojom.MtpManager" ],
-        "device:nfc": [ "device.mojom.NFCProvider" ],
-        "device:power_monitor": [ "device.mojom.PowerMonitor" ],
-        "device:screen_orientation": [ "device.mojom.ScreenOrientationListener" ],
-        "device:serial": [ "device.mojom.SerialPortManager" ],
-        "device:time_zone_monitor": [ "device.mojom.TimeZoneMonitor" ],
-        "device:usb": [ "device.mojom.UsbDeviceManager" ],
-        "device:usb_test": [ "device.mojom.UsbDeviceManagerTest" ],
-        "device:vibration": [ "device.mojom.VibrationManager" ],
-        "device:wake_lock": [ "device.mojom.WakeLockProvider" ]
-      }
-    }
-  }
-}
diff --git a/services/device/public/cpp/BUILD.gn b/services/device/public/cpp/BUILD.gn
index abc3fdd..6635bfa 100644
--- a/services/device/public/cpp/BUILD.gn
+++ b/services/device/public/cpp/BUILD.gn
@@ -19,3 +19,23 @@
 
   defines = [ "DEVICE_FEATURES_IMPLEMENTATION" ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//device/usb/public/mojom",
+    "//device/usb/public/mojom:test",
+    "//services/device/public/mojom",
+    "//services/device/public/mojom:generic_sensor",
+    "//services/service_manager/public/cpp",
+  ]
+
+  if (is_chromeos && use_dbus) {
+    defines = [ "USE_DBUS=1" ]
+  }
+}
diff --git a/services/device/public/cpp/OWNERS b/services/device/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/services/device/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/device/public/cpp/generic_sensor/BUILD.gn b/services/device/public/cpp/generic_sensor/BUILD.gn
index 3c503b1..2eaa63b 100644
--- a/services/device/public/cpp/generic_sensor/BUILD.gn
+++ b/services/device/public/cpp/generic_sensor/BUILD.gn
@@ -4,8 +4,6 @@
 
 source_set("generic_sensor") {
   sources = [
-    "platform_sensor_configuration.cc",
-    "platform_sensor_configuration.h",
     "sensor_reading.cc",
     "sensor_reading.h",
     "sensor_reading_shared_buffer_reader.cc",
@@ -15,6 +13,7 @@
   ]
 
   public_deps = [
+    ":sensor_configuration",
     "//services/device/public/mojom:generic_sensor",
   ]
 
@@ -23,3 +22,14 @@
     "//device/base/synchronization",
   ]
 }
+
+source_set("sensor_configuration") {
+  sources = [
+    "platform_sensor_configuration.cc",
+    "platform_sensor_configuration.h",
+  ]
+
+  deps = [
+    "//base",
+  ]
+}
diff --git a/services/device/public/cpp/manifest.cc b/services/device/public/cpp/manifest.cc
new file mode 100644
index 0000000..ff894def
--- /dev/null
+++ b/services/device/public/cpp/manifest.cc
@@ -0,0 +1,113 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/device/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "device/usb/public/mojom/device_manager.mojom.h"
+#include "device/usb/public/mojom/device_manager_test.mojom.h"
+#include "services/device/public/mojom/battery_monitor.mojom.h"
+#include "services/device/public/mojom/bluetooth_system.mojom.h"
+#include "services/device/public/mojom/constants.mojom.h"
+#include "services/device/public/mojom/fingerprint.mojom.h"
+#include "services/device/public/mojom/geolocation_config.mojom.h"
+#include "services/device/public/mojom/geolocation_context.mojom.h"
+#include "services/device/public/mojom/geolocation_control.mojom.h"
+#include "services/device/public/mojom/hid.mojom.h"
+#include "services/device/public/mojom/input_service.mojom.h"
+#include "services/device/public/mojom/nfc_provider.mojom.h"
+#include "services/device/public/mojom/power_monitor.mojom.h"
+#include "services/device/public/mojom/public_ip_address_geolocation_provider.mojom.h"
+#include "services/device/public/mojom/screen_orientation.mojom.h"
+#include "services/device/public/mojom/sensor_provider.mojom.h"
+#include "services/device/public/mojom/serial.mojom.h"
+#include "services/device/public/mojom/time_zone_monitor.mojom.h"
+#include "services/device/public/mojom/vibration_manager.mojom.h"
+#include "services/device/public/mojom/wake_lock_provider.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+#if defined(USE_DBUS)
+#include "services/device/public/mojom/mtp_manager.mojom.h"
+#endif
+
+namespace device {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest {
+    service_manager::ManifestBuilder()
+        .WithServiceName(mojom::kServiceName)
+        .WithDisplayName("Device Service")
+        .WithOptions(service_manager::ManifestOptionsBuilder()
+                         .WithInstanceSharingPolicy(
+                             service_manager::Manifest::InstanceSharingPolicy::
+                                 kSharedAcrossGroups)
+                         .Build())
+        .ExposeCapability(
+            "device:battery_monitor",
+            service_manager::Manifest::InterfaceList<mojom::BatteryMonitor>())
+        .ExposeCapability("device:bluetooth_system",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::BluetoothSystemFactory>())
+        .ExposeCapability(
+            "device:fingerprint",
+            service_manager::Manifest::InterfaceList<mojom::Fingerprint>())
+        .ExposeCapability(
+            "device:generic_sensor",
+            service_manager::Manifest::InterfaceList<mojom::SensorProvider>())
+        .ExposeCapability("device:geolocation",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::GeolocationContext>())
+        .ExposeCapability("device:geolocation_config",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::GeolocationConfig>())
+        .ExposeCapability("device:geolocation_control",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::GeolocationControl>())
+        .ExposeCapability(
+            "device:hid",
+            service_manager::Manifest::InterfaceList<mojom::HidManager>())
+        .ExposeCapability("device:ip_geolocator",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::PublicIpAddressGeolocationProvider>())
+        .ExposeCapability("device:input_service",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::InputDeviceManager>())
+        .ExposeCapability(
+            "device:nfc",
+            service_manager::Manifest::InterfaceList<mojom::NFCProvider>())
+        .ExposeCapability(
+            "device:power_monitor",
+            service_manager::Manifest::InterfaceList<mojom::PowerMonitor>())
+        .ExposeCapability("device:screen_orientation",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::ScreenOrientationListener>())
+        .ExposeCapability("device:serial",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::SerialPortManager>())
+        .ExposeCapability(
+            "device:time_zone_monitor",
+            service_manager::Manifest::InterfaceList<mojom::TimeZoneMonitor>())
+        .ExposeCapability(
+            "device:usb",
+            service_manager::Manifest::InterfaceList<mojom::UsbDeviceManager>())
+        .ExposeCapability("device:usb_test",
+                          service_manager::Manifest::InterfaceList<
+                              mojom::UsbDeviceManagerTest>())
+        .ExposeCapability(
+            "device:vibration",
+            service_manager::Manifest::InterfaceList<mojom::VibrationManager>())
+        .ExposeCapability(
+            "device:wake_lock",
+            service_manager::Manifest::InterfaceList<mojom::WakeLockProvider>())
+#if defined(USE_DBUS)
+        .ExposeCapability(
+            "device:mtp",
+            service_manager::Manifest::InterfaceList<mojom::MtpManager>())
+#endif
+        .Build()
+  };
+  return *manifest;
+}
+
+}  // namespace device
diff --git a/services/device/public/cpp/manifest.h b/services/device/public/cpp/manifest.h
new file mode 100644
index 0000000..b189a91
--- /dev/null
+++ b/services/device/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_DEVICE_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_DEVICE_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace device {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace device
+
+#endif  // SERVICES_DEVICE_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/device/public/mojom/bluetooth_system.mojom b/services/device/public/mojom/bluetooth_system.mojom
index 58f178df..84fae98b 100644
--- a/services/device/public/mojom/bluetooth_system.mojom
+++ b/services/device/public/mojom/bluetooth_system.mojom
@@ -101,19 +101,27 @@
     // Unknown failure when sending the command to the BT radio.
     kFailedUnknownReason,
     // Can't use Bluetooth right now e.g. a BT radio is not present.
-    kBluetoothUnavailable,
+    kFailedBluetoothUnavailable,
+    // Can't change the radio state right now, there is an in-progress call.
+    kFailedInProgress,
   };
 
   // Attempts to change the state of the Bluetooth to `kPoweredOn` if |powered|
-  // and `kPoweredOff` otherwise . Callback is run with `kSuccess if the command
-  // was successfully sent to the BT radio. The state immediately changes to
-  // kTransitioning and once the BT radio actually changes state
-  // BluetoothSystemClient::OnStateChanged will be called.
-  // TODO(https://crbug.com/896113): This function is missing two features:
+  // and `kPoweredOff` otherwise . Callback is run with `kSuccess` if the
+  // command was successfully sent to the BT radio. The state immediately
+  // changes to kTransitioning and once the BT radio actually changes state
+  // BluetoothSystemClient::OnStateChanged will be called. Does not support
+  // concurrent calls.
+  //
+  // To keep the implementation simple and because no clients need it (UI
+  // clients disable the power toggle during `kTransitioning`), this function
+  // does not support concurrent calls. Meaning, if there is a pending call to
+  // SetPowered(), all new calls to SetPowered() will immediately fail with
+  // `kFailedInProgress`.
+  //
+  // TODO(https://crbug.com/896113): This function is missing one feature:
   //  1. The new state should be saved in the user's pref so that the next time
-  //     the machine turns off the state matches the user pref.
-  //  2. Support concurrent calls; currently BlueZ just drops other calls if
-  //     there is one in progress already.
+  //     the machine restarts the state matches the user pref.
   SetPowered(bool powered) => (SetPoweredResult result);
 
   // Whether the BT radio is scanning for devices.
@@ -137,7 +145,7 @@
     kFailedUnknownReason,
     // Can't use Bluetooth right now e.g. BT radio is off, not present, or
     // transitioning between states.
-    kBluetoothUnavailable,
+    kFailedBluetoothUnavailable,
     // TODO(https://crbug.com/897996): Add more specific error codes.
   };
 
@@ -157,7 +165,7 @@
     // Unknown failure when sending the command to the BT radio.
     kFailedUnknownReason,
     // Can't use Bluetooth right now e.g. BT radio is off, or not present.
-    kBluetoothUnavailable,
+    kFailedBluetoothUnavailable,
     // TODO(https://crbug.com/897996): Add more specific error codes.
   };
 
diff --git a/services/device/public/mojom/sensor.typemap b/services/device/public/mojom/sensor.typemap
index 2d65c5e..46fc9b9f 100644
--- a/services/device/public/mojom/sensor.typemap
+++ b/services/device/public/mojom/sensor.typemap
@@ -6,6 +6,9 @@
 public_headers = [
   "//services/device/public/cpp/generic_sensor/platform_sensor_configuration.h",
 ]
+public_deps = [
+  "//services/device/public/cpp/generic_sensor:sensor_configuration",
+]
 traits_headers =
     [ "//services/device/public/cpp/generic_sensor/sensor_mojom_traits.h" ]
 sources = [
diff --git a/services/file/BUILD.gn b/services/file/BUILD.gn
index fd45886..e017dc9 100644
--- a/services/file/BUILD.gn
+++ b/services/file/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 source_set("lib") {
   sources = [
     "file_service.cc",
@@ -29,8 +27,3 @@
     "//url",
   ]
 }
-
-service_manifest("manifest") {
-  name = "file"
-  source = "manifest.json"
-}
diff --git a/services/file/OWNERS b/services/file/OWNERS
index 6bff3ba..e06924a 100644
--- a/services/file/OWNERS
+++ b/services/file/OWNERS
@@ -1,4 +1 @@
 rockot@google.com
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/services/file/manifest.json b/services/file/manifest.json
deleted file mode 100644
index a02f9d6..0000000
--- a/services/file/manifest.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "name": "file",
-  "display_name": "File Service",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "file:filesystem": [ "file.mojom.FileSystem" ],
-        "file:leveldb": [ "leveldb.mojom.LevelDBService" ]
-      },
-      "requires": {
-        "*": [ "app" ]
-      }
-    }
-  }
-}
diff --git a/services/file/public/cpp/BUILD.gn b/services/file/public/cpp/BUILD.gn
new file mode 100644
index 0000000..65fcbf1
--- /dev/null
+++ b/services/file/public/cpp/BUILD.gn
@@ -0,0 +1,17 @@
+# 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.
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//components/services/leveldb/public/interfaces",
+    "//services/file/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/file/public/cpp/OWNERS b/services/file/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/services/file/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/file/public/cpp/manifest.cc b/services/file/public/cpp/manifest.cc
new file mode 100644
index 0000000..6577002a
--- /dev/null
+++ b/services/file/public/cpp/manifest.cc
@@ -0,0 +1,30 @@
+// 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 "services/file/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "components/services/leveldb/public/interfaces/leveldb.mojom.h"
+#include "services/file/public/mojom/constants.mojom.h"
+#include "services/file/public/mojom/file_system.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace file {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("File Service")
+          .ExposeCapability("file:leveldb",
+                            service_manager::Manifest::InterfaceList<
+                                leveldb::mojom::LevelDBService>())
+          .ExposeCapability(
+              "file:filesystem",
+              service_manager::Manifest::InterfaceList<mojom::FileSystem>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace file
diff --git a/services/file/public/cpp/manifest.h b/services/file/public/cpp/manifest.h
new file mode 100644
index 0000000..1d455fb3
--- /dev/null
+++ b/services/file/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_FILE_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_FILE_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace file {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace file
+
+#endif  // SERVICES_FILE_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/identity/BUILD.gn b/services/identity/BUILD.gn
index d71e358..ba278ece2 100644
--- a/services/identity/BUILD.gn
+++ b/services/identity/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 if (is_android) {
   import("//build/config/android/rules.gni")
 }
@@ -29,11 +27,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "identity"
-  source = "manifest.json"
-}
-
 source_set("tests") {
   testonly = true
   deps = [
diff --git a/services/identity/OWNERS b/services/identity/OWNERS
index d913972..5def59b 100644
--- a/services/identity/OWNERS
+++ b/services/identity/OWNERS
@@ -4,6 +4,3 @@
 droger@chromium.org
 msarda@chromium.org
 sdefresne@chromium.org
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/services/identity/manifest.json b/services/identity/manifest.json
deleted file mode 100644
index 3e600a4..0000000
--- a/services/identity/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "name": "identity",
-  "display_name": "Identity Service",
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "identity_manager" : [ "identity.mojom.IdentityManager" ]
-      }
-    }
-  }
-}
diff --git a/services/identity/public/cpp/BUILD.gn b/services/identity/public/cpp/BUILD.gn
index fa8a1905..f8268045 100644
--- a/services/identity/public/cpp/BUILD.gn
+++ b/services/identity/public/cpp/BUILD.gn
@@ -93,3 +93,16 @@
     "//testing/gtest",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/identity/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/identity/public/cpp/OWNERS b/services/identity/public/cpp/OWNERS
index 7aebc8abb..59d61d19 100644
--- a/services/identity/public/cpp/OWNERS
+++ b/services/identity/public/cpp/OWNERS
@@ -2,3 +2,7 @@
 per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
 per-file *.typemap=set noparent
 per-file *.typemap=file://ipc/SECURITY_OWNERS
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/identity/public/cpp/manifest.cc b/services/identity/public/cpp/manifest.cc
new file mode 100644
index 0000000..ab7926d
--- /dev/null
+++ b/services/identity/public/cpp/manifest.cc
@@ -0,0 +1,26 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "services/identity/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/identity/public/mojom/constants.mojom.h"
+#include "services/identity/public/mojom/identity_manager.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace identity {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Identity Service")
+          .ExposeCapability("identity_manager",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::IdentityManager>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace identity
diff --git a/services/identity/public/cpp/manifest.h b/services/identity/public/cpp/manifest.h
new file mode 100644
index 0000000..be56997
--- /dev/null
+++ b/services/identity/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_IDENTITY_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_IDENTITY_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace identity {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace identity
+
+#endif  // SERVICES_IDENTITY_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/media_session/BUILD.gn b/services/media_session/BUILD.gn
index c2678765..3228a8b 100644
--- a/services/media_session/BUILD.gn
+++ b/services/media_session/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
 import("//testing/test.gni")
 
 # There should be only one media session service. It is currently in the
@@ -34,11 +33,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "media_session"
-  source = "manifest.json"
-}
-
 source_set("tests") {
   testonly = true
   sources = [
diff --git a/services/media_session/OWNERS b/services/media_session/OWNERS
index 5d7ebfd..6cd614d 100644
--- a/services/media_session/OWNERS
+++ b/services/media_session/OWNERS
@@ -1,10 +1,6 @@
 beccahughes@chromium.org
 mlamouri@chromium.org
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 
-per-file unittest_manifest.json=set noparent
-per-file unittest_manifest.json=file://ipc/SECURITY_OWNERS
 
 # Component: Internals>Media>Session
diff --git a/services/media_session/manifest.json b/services/media_session/manifest.json
deleted file mode 100644
index d9edfb6..0000000
--- a/services/media_session/manifest.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
-  "name": "media_session",
-  "display_name": "Media Session Service",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "app": [
-          "media_session.mojom.AudioFocusManager",
-          "media_session.mojom.AudioFocusManagerDebug",
-          "media_session.mojom.MediaControllerManager"
-        ],
-        "tests": [ "*" ]
-      }
-    }
-  }
-}
diff --git a/services/media_session/public/cpp/BUILD.gn b/services/media_session/public/cpp/BUILD.gn
index e598fe1..a82050d 100644
--- a/services/media_session/public/cpp/BUILD.gn
+++ b/services/media_session/public/cpp/BUILD.gn
@@ -48,3 +48,16 @@
     "//testing/gtest",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/media_session/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/media_session/public/cpp/OWNERS b/services/media_session/public/cpp/OWNERS
index 7aebc8abb..59d61d19 100644
--- a/services/media_session/public/cpp/OWNERS
+++ b/services/media_session/public/cpp/OWNERS
@@ -2,3 +2,7 @@
 per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
 per-file *.typemap=set noparent
 per-file *.typemap=file://ipc/SECURITY_OWNERS
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/media_session/public/cpp/manifest.cc b/services/media_session/public/cpp/manifest.cc
new file mode 100644
index 0000000..f70928f9
--- /dev/null
+++ b/services/media_session/public/cpp/manifest.cc
@@ -0,0 +1,37 @@
+// 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 "services/media_session/public/cpp/manifest.h"
+
+#include <set>
+
+#include "base/no_destructor.h"
+#include "services/media_session/public/mojom/audio_focus.mojom.h"
+#include "services/media_session/public/mojom/constants.mojom.h"
+#include "services/media_session/public/mojom/media_controller.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace media_session {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Media Session Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability(
+              "app",
+              service_manager::Manifest::InterfaceList<
+                  mojom::AudioFocusManager, mojom::AudioFocusManagerDebug,
+                  mojom::MediaControllerManager>())
+          .ExposeCapability("tests", std::set<const char*>{"*"})
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace media_session
diff --git a/services/media_session/public/cpp/manifest.h b/services/media_session/public/cpp/manifest.h
new file mode 100644
index 0000000..5124c2b
--- /dev/null
+++ b/services/media_session/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_MEDIA_SESSION_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_MEDIA_SESSION_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace media_session {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace media_session
+
+#endif  // SERVICES_MEDIA_SESSION_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/metrics/BUILD.gn b/services/metrics/BUILD.gn
index a6c81a755..bb2ff72 100644
--- a/services/metrics/BUILD.gn
+++ b/services/metrics/BUILD.gn
@@ -2,13 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
-service_manifest("manifest") {
-  name = "metrics"
-  source = "manifest.json"
-}
-
 source_set("metrics") {
   sources = [
     "metrics_mojo_service.cc",
diff --git a/services/metrics/OWNERS b/services/metrics/OWNERS
index c109a36..c901116 100644
--- a/services/metrics/OWNERS
+++ b/services/metrics/OWNERS
@@ -1,6 +1,4 @@
 file://base/metrics/OWNERS
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 
 # COMPONENT: Internals>Metrics
diff --git a/services/metrics/manifest.json b/services/metrics/manifest.json
deleted file mode 100644
index 10ae675..0000000
--- a/services/metrics/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "metrics",
-  "display_name": "Metrics Service",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "url_keyed_metrics": [
-          "ukm.mojom.UkmRecorderInterface"
-        ]
-      }
-    }
-  }
-}
diff --git a/services/metrics/public/cpp/BUILD.gn b/services/metrics/public/cpp/BUILD.gn
index 154b9dcb..2101ef4 100644
--- a/services/metrics/public/cpp/BUILD.gn
+++ b/services/metrics/public/cpp/BUILD.gn
@@ -97,3 +97,16 @@
     "//base",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/metrics/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/metrics/public/cpp/OWNERS b/services/metrics/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/services/metrics/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/metrics/public/cpp/manifest.cc b/services/metrics/public/cpp/manifest.cc
new file mode 100644
index 0000000..e5bfd5f
--- /dev/null
+++ b/services/metrics/public/cpp/manifest.cc
@@ -0,0 +1,31 @@
+// 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 "services/metrics/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/metrics/public/mojom/constants.mojom.h"
+#include "services/metrics/public/mojom/ukm_interface.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace metrics {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kMetricsServiceName)
+          .WithDisplayName("Metrics Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability("url_keyed_metrics",
+                            service_manager::Manifest::InterfaceList<
+                                ukm::mojom::UkmRecorderInterface>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace metrics
diff --git a/services/metrics/public/cpp/manifest.h b/services/metrics/public/cpp/manifest.h
new file mode 100644
index 0000000..b082fea
--- /dev/null
+++ b/services/metrics/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_METRICS_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_METRICS_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace metrics {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace metrics
+
+#endif  // SERVICES_METRICS_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/network/BUILD.gn b/services/network/BUILD.gn
index 73613c7..13b8b829 100644
--- a/services/network/BUILD.gn
+++ b/services/network/BUILD.gn
@@ -6,7 +6,6 @@
 import("//mojo/public/tools/bindings/mojom.gni")
 import("//net/features.gni")
 import("//services/network/public/cpp/features.gni")
-import("//services/service_manager/public/service_manifest.gni")
 
 jumbo_component("network_service") {
   sources = [
@@ -439,8 +438,3 @@
     "//testing/gtest",
   ]
 }
-
-service_manifest("manifest") {
-  name = "network"
-  source = "manifest.json"
-}
diff --git a/services/network/OWNERS b/services/network/OWNERS
index 90fdb34..65e667b 100644
--- a/services/network/OWNERS
+++ b/services/network/OWNERS
@@ -21,8 +21,6 @@
 per-file cert_verifier_with_trust_anchors*=file://chromeos/policy/OWNERS
 per-file cert_verify_proc_chromeos*=file://chromeos/policy/OWNERS
 
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
 per-file *_type_converter*.*=set noparent
 per-file *_type_converter*.*=file://ipc/SECURITY_OWNERS
 
diff --git a/services/network/manifest.json b/services/network/manifest.json
deleted file mode 100644
index 7819f9e..0000000
--- a/services/network/manifest.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-  "name": "network",
-  "display_name": "Network Service",
-  "sandbox_type": "network",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "network_service": [
-          "network.mojom.NetworkService"
-        ],
-        "test": [
-          "network.mojom.NetworkServiceTest"
-        ],
-        "url_loader": [
-          "network.mojom.URLLoaderFactory"
-        ]
-      }
-    }
-  }
-}
diff --git a/services/network/public/cpp/BUILD.gn b/services/network/public/cpp/BUILD.gn
index 9cdb2d23..b6fdba09 100644
--- a/services/network/public/cpp/BUILD.gn
+++ b/services/network/public/cpp/BUILD.gn
@@ -216,3 +216,16 @@
     ":buildflags",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/network/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/network/public/cpp/OWNERS b/services/network/public/cpp/OWNERS
index 1102a33..3761be3 100644
--- a/services/network/public/cpp/OWNERS
+++ b/services/network/public/cpp/OWNERS
@@ -6,3 +6,7 @@
 per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
 per-file *.typemap=set noparent
 per-file *.typemap=file://ipc/SECURITY_OWNERS
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/network/public/cpp/manifest.cc b/services/network/public/cpp/manifest.cc
new file mode 100644
index 0000000..5fe51f97
--- /dev/null
+++ b/services/network/public/cpp/manifest.cc
@@ -0,0 +1,34 @@
+// 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 "services/network/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/network/public/mojom/network_service.mojom.h"
+#include "services/network/public/mojom/network_service_test.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace network {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName("network")
+          .WithDisplayName("Network Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithSandboxType("network")
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability("test", service_manager::Manifest::InterfaceList<
+                                        mojom::NetworkServiceTest>())
+          .ExposeCapability(
+              "network_service",
+              service_manager::Manifest::InterfaceList<mojom::NetworkService>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace network
diff --git a/services/network/public/cpp/manifest.h b/services/network/public/cpp/manifest.h
new file mode 100644
index 0000000..8277157
--- /dev/null
+++ b/services/network/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_NETWORK_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_NETWORK_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace network {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace network
+
+#endif  // SERVICES_NETWORK_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/proxy_resolver/BUILD.gn b/services/proxy_resolver/BUILD.gn
index 5db8551..da217c8 100644
--- a/services/proxy_resolver/BUILD.gn
+++ b/services/proxy_resolver/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 source_set("lib") {
   sources = [
     "host_resolver_mojo.cc",
@@ -57,8 +55,3 @@
 
   configs += [ "//v8:external_startup_data" ]
 }
-
-service_manifest("proxy_resolver_manifest") {
-  name = "proxy_resolver"
-  source = "manifest.json"
-}
diff --git a/services/proxy_resolver/OWNERS b/services/proxy_resolver/OWNERS
index 310d6b2..28361a0 100644
--- a/services/proxy_resolver/OWNERS
+++ b/services/proxy_resolver/OWNERS
@@ -1,4 +1 @@
 file://services/network/OWNERS
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/services/proxy_resolver/manifest.json b/services/proxy_resolver/manifest.json
deleted file mode 100644
index 266d1da7..0000000
--- a/services/proxy_resolver/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "proxy_resolver",
-  "display_name": "Proxy resolver",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "factory": [ "proxy_resolver.mojom.ProxyResolverFactory" ]
-       }
-     }
-  }
-}
\ No newline at end of file
diff --git a/services/proxy_resolver/public/cpp/BUILD.gn b/services/proxy_resolver/public/cpp/BUILD.gn
new file mode 100644
index 0000000..b8ae76a
--- /dev/null
+++ b/services/proxy_resolver/public/cpp/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/proxy_resolver/public/mojom",
+    "//services/service_manager/public/cpp",
+  ]
+}
diff --git a/services/proxy_resolver/public/cpp/OWNERS b/services/proxy_resolver/public/cpp/OWNERS
index 591a684..68cd819d 100644
--- a/services/proxy_resolver/public/cpp/OWNERS
+++ b/services/proxy_resolver/public/cpp/OWNERS
@@ -4,3 +4,7 @@
 per-file *_struct_traits*.*=file://ipc/SECURITY_OWNERS
 per-file *.typemap=set noparent
 per-file *.typemap=file://ipc/SECURITY_OWNERS
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/proxy_resolver/public/cpp/manifest.cc b/services/proxy_resolver/public/cpp/manifest.cc
new file mode 100644
index 0000000..585dd68
--- /dev/null
+++ b/services/proxy_resolver/public/cpp/manifest.cc
@@ -0,0 +1,29 @@
+// 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 "services/proxy_resolver/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/proxy_resolver/public/mojom/proxy_resolver.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+
+namespace proxy_resolver {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kProxyResolverServiceName)
+          .WithDisplayName("Proxy resolver")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability("factory", service_manager::Manifest::InterfaceList<
+                                           mojom::ProxyResolverFactory>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace proxy_resolver
diff --git a/services/proxy_resolver/public/cpp/manifest.h b/services/proxy_resolver/public/cpp/manifest.h
new file mode 100644
index 0000000..0633d14
--- /dev/null
+++ b/services/proxy_resolver/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_PROXY_RESOLVER_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_PROXY_RESOLVER_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace proxy_resolver {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace proxy_resolver
+
+#endif  // SERVICES_PROXY_RESOLVER_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/resource_coordinator/BUILD.gn b/services/resource_coordinator/BUILD.gn
index ba407a5..468e597 100644
--- a/services/resource_coordinator/BUILD.gn
+++ b/services/resource_coordinator/BUILD.gn
@@ -2,8 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
-
 # There should be only one resource coordinator. It is currently
 # in the browser process. So, only //content/browser should link to this target.
 # Others modules should only need the public targets.
@@ -39,11 +37,6 @@
   ]
 }
 
-service_manifest("manifest") {
-  name = "resource_coordinator"
-  source = "manifest.json"
-}
-
 source_set("tests") {
   testonly = true
 
diff --git a/services/resource_coordinator/OWNERS b/services/resource_coordinator/OWNERS
index 5ee3aa68..c55119f 100644
--- a/services/resource_coordinator/OWNERS
+++ b/services/resource_coordinator/OWNERS
@@ -6,6 +6,3 @@
 zhenw@chromium.org
 
 per-file BUILD.gn=file://services/resource_coordinator/memory_instrumentation/OWNERS
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/services/resource_coordinator/manifest.json b/services/resource_coordinator/manifest.json
deleted file mode 100644
index d1ed8ff..0000000
--- a/services/resource_coordinator/manifest.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
-  "name": "resource_coordinator",
-  "display_name": "Global Resource Coordinator",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "app": [
-          "memory_instrumentation.mojom.Coordinator"
-        ],
-        "heap_profiler_helper": [ "memory_instrumentation.mojom.HeapProfilerHelper" ],
-        "tests": [ "*" ]
-      },
-      "requires": {
-        "service_manager": [
-          "service_manager:service_manager"
-        ],
-        "metrics": [
-          "url_keyed_metrics"
-        ]
-      }
-    }
-  }
-}
diff --git a/services/resource_coordinator/public/cpp/BUILD.gn b/services/resource_coordinator/public/cpp/BUILD.gn
index 8d8620e..dcc3447b 100644
--- a/services/resource_coordinator/public/cpp/BUILD.gn
+++ b/services/resource_coordinator/public/cpp/BUILD.gn
@@ -44,3 +44,18 @@
     "//services/service_manager/public/cpp",
   ]
 }
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/metrics/public/mojom",
+    "//services/resource_coordinator/public/mojom",
+    "//services/service_manager/public/cpp",
+    "//services/service_manager/public/mojom",
+  ]
+}
diff --git a/services/resource_coordinator/public/cpp/OWNERS b/services/resource_coordinator/public/cpp/OWNERS
index a605b825..5e4bf1e 100644
--- a/services/resource_coordinator/public/cpp/OWNERS
+++ b/services/resource_coordinator/public/cpp/OWNERS
@@ -5,3 +5,7 @@
 
 per-file *_mojom_traits*.*=set noparent
 per-file *_mojom_traits*.*=file://ipc/SECURITY_OWNERS
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/resource_coordinator/public/cpp/manifest.cc b/services/resource_coordinator/public/cpp/manifest.cc
new file mode 100644
index 0000000..073bd38
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/manifest.cc
@@ -0,0 +1,44 @@
+// 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 "services/resource_coordinator/public/cpp/manifest.h"
+
+#include <set>
+
+#include "base/no_destructor.h"
+#include "services/metrics/public/mojom/constants.mojom.h"
+#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
+#include "services/resource_coordinator/public/mojom/service_constants.mojom.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+#include "services/service_manager/public/mojom/constants.mojom.h"
+
+namespace resource_coordinator {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Global Resource Coordinator")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability("app",
+                            service_manager::Manifest::InterfaceList<
+                                memory_instrumentation::mojom::Coordinator>())
+          .ExposeCapability(
+              "heap_profiler_helper",
+              service_manager::Manifest::InterfaceList<
+                  memory_instrumentation::mojom::HeapProfilerHelper>())
+          .ExposeCapability("tests", std::set<const char*>{"*"})
+          .RequireCapability(metrics::mojom::kMetricsServiceName,
+                             "url_keyed_metrics")
+          .RequireCapability(service_manager::mojom::kServiceName,
+                             "service_manager:service_manager")
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace resource_coordinator
diff --git a/services/resource_coordinator/public/cpp/manifest.h b/services/resource_coordinator/public/cpp/manifest.h
new file mode 100644
index 0000000..fdf1346
--- /dev/null
+++ b/services/resource_coordinator/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace resource_coordinator {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace resource_coordinator
+
+#endif  // SERVICES_RESOURCE_COORDINATOR_PUBLIC_CPP_MANIFEST_H_
diff --git a/services/shape_detection/BUILD.gn b/services/shape_detection/BUILD.gn
index b42d92d..6cb31fed 100644
--- a/services/shape_detection/BUILD.gn
+++ b/services/shape_detection/BUILD.gn
@@ -2,7 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//services/service_manager/public/service_manifest.gni")
 import("//testing/test.gni")
 
 source_set("lib") {
@@ -114,11 +113,6 @@
   }
 }
 
-service_manifest("manifest") {
-  name = "shape_detection"
-  source = "manifest.json"
-}
-
 source_set("tests") {
   testonly = true
   sources = [
diff --git a/services/shape_detection/OWNERS b/services/shape_detection/OWNERS
index 16d84b0d..0e57d5f 100644
--- a/services/shape_detection/OWNERS
+++ b/services/shape_detection/OWNERS
@@ -3,6 +3,3 @@
 
 mcasas@chromium.org
 reillyg@chromium.org
-
-per-file manifest.json=set noparent
-per-file manifest.json=file://ipc/SECURITY_OWNERS
diff --git a/services/shape_detection/manifest.json b/services/shape_detection/manifest.json
deleted file mode 100644
index 3173d63..0000000
--- a/services/shape_detection/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  "name": "shape_detection",
-  "display_name": "Shape Detection Service",
-  "options" : {
-    "instance_sharing" : "shared_instance_across_users"
-  },
-  "interface_provider_specs": {
-    "service_manager:connector": {
-      "provides": {
-        "face_detection": [ "shape_detection.mojom.FaceDetectionProvider" ],
-        "barcode_detection": [ "shape_detection.mojom.BarcodeDetectionProvider" ],
-        "text_detection": [ "shape_detection.mojom.TextDetection" ]
-      }
-    }
-  }
-}
diff --git a/services/shape_detection/public/cpp/BUILD.gn b/services/shape_detection/public/cpp/BUILD.gn
new file mode 100644
index 0000000..c134377
--- /dev/null
+++ b/services/shape_detection/public/cpp/BUILD.gn
@@ -0,0 +1,16 @@
+# 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.
+
+source_set("manifest") {
+  sources = [
+    "manifest.cc",
+    "manifest.h",
+  ]
+
+  deps = [
+    "//base",
+    "//services/service_manager/public/cpp",
+    "//services/shape_detection/public/mojom",
+  ]
+}
diff --git a/services/shape_detection/public/cpp/OWNERS b/services/shape_detection/public/cpp/OWNERS
new file mode 100644
index 0000000..6faeaa47
--- /dev/null
+++ b/services/shape_detection/public/cpp/OWNERS
@@ -0,0 +1,4 @@
+per-file manifest.cc=set noparent
+per-file manifest.cc=file://ipc/SECURITY_OWNERS
+per-file manifest.h=set noparent
+per-file manifest.h=file://ipc/SECURITY_OWNERS
diff --git a/services/shape_detection/public/cpp/manifest.cc b/services/shape_detection/public/cpp/manifest.cc
new file mode 100644
index 0000000..409fdd1
--- /dev/null
+++ b/services/shape_detection/public/cpp/manifest.cc
@@ -0,0 +1,39 @@
+// 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 "services/shape_detection/public/cpp/manifest.h"
+
+#include "base/no_destructor.h"
+#include "services/service_manager/public/cpp/manifest_builder.h"
+#include "services/shape_detection/public/mojom/barcodedetection_provider.mojom.h"
+#include "services/shape_detection/public/mojom/constants.mojom.h"
+#include "services/shape_detection/public/mojom/facedetection_provider.mojom.h"
+#include "services/shape_detection/public/mojom/textdetection.mojom.h"
+
+namespace shape_detection {
+
+const service_manager::Manifest& GetManifest() {
+  static base::NoDestructor<service_manager::Manifest> manifest{
+      service_manager::ManifestBuilder()
+          .WithServiceName(mojom::kServiceName)
+          .WithDisplayName("Shape Detection Service")
+          .WithOptions(service_manager::ManifestOptionsBuilder()
+                           .WithInstanceSharingPolicy(
+                               service_manager::Manifest::
+                                   InstanceSharingPolicy::kSharedAcrossGroups)
+                           .Build())
+          .ExposeCapability("barcode_detection",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::BarcodeDetectionProvider>())
+          .ExposeCapability("face_detection",
+                            service_manager::Manifest::InterfaceList<
+                                mojom::FaceDetectionProvider>())
+          .ExposeCapability(
+              "text_detection",
+              service_manager::Manifest::InterfaceList<mojom::TextDetection>())
+          .Build()};
+  return *manifest;
+}
+
+}  // namespace shape_detection
diff --git a/services/shape_detection/public/cpp/manifest.h b/services/shape_detection/public/cpp/manifest.h
new file mode 100644
index 0000000..413e6a5
--- /dev/null
+++ b/services/shape_detection/public/cpp/manifest.h
@@ -0,0 +1,16 @@
+// 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 SERVICES_SHAPE_DETECTION_PUBLIC_CPP_MANIFEST_H_
+#define SERVICES_SHAPE_DETECTION_PUBLIC_CPP_MANIFEST_H_
+
+#include "services/service_manager/public/cpp/manifest.h"
+
+namespace shape_detection {
+
+const service_manager::Manifest& GetManifest();
+
+}  // namespace shape_detection
+
+#endif  // SERVICES_SHAPE_DETECTION_PUBLIC_CPP_MANIFEST_H_
diff --git a/testing/buildbot/gn_isolate_map.pyl b/testing/buildbot/gn_isolate_map.pyl
index cf813ff..80512bb 100644
--- a/testing/buildbot/gn_isolate_map.pyl
+++ b/testing/buildbot/gn_isolate_map.pyl
@@ -414,6 +414,10 @@
     "label": "//third_party/cacheinvalidation:cacheinvalidation_unittests",
     "type": "console_test_launcher",
   },
+  "captured_sites_interactive_tests": {
+    "label": "//chrome/test:captured_sites_interactive_tests",
+    "type": "windowed_test_launcher",
+  },
   "capture_unittests": {
     "label": "//media/capture:capture_unittests",
     "type": "windowed_test_launcher",
diff --git a/testing/buildbot/manage.py b/testing/buildbot/manage.py
index e22e539..e2c68f4 100755
--- a/testing/buildbot/manage.py
+++ b/testing/buildbot/manage.py
@@ -80,6 +80,7 @@
   # These targets are listed only in build-side recipes.
   'All_syzygy',
   'blink_tests',
+  'captured_sites_interactive_tests',
   'cast_shell',
   'cast_shell_apk',
   'chrome_official_builder',
diff --git a/third_party/blink/common/feature_policy/feature_policy.cc b/third_party/blink/common/feature_policy/feature_policy.cc
index af7216c2..fbd83fda 100644
--- a/third_party/blink/common/feature_policy/feature_policy.cc
+++ b/third_party/blink/common/feature_policy/feature_policy.cc
@@ -301,6 +301,8 @@
         FeaturePolicy::FeatureDefault::EnableForAll},
        {mojom::FeaturePolicyFeature::kScript,
         FeaturePolicy::FeatureDefault::EnableForAll},
+       {mojom::FeaturePolicyFeature::kSerial,
+        FeaturePolicy::FeatureDefault::EnableForSelf},
        {mojom::FeaturePolicyFeature::kSpeaker,
         FeaturePolicy::FeatureDefault::EnableForSelf},
        {mojom::FeaturePolicyFeature::kSyncScript,
diff --git a/third_party/blink/public/mojom/feature_policy/feature_policy.mojom b/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
index d5b45bf..d470f266 100644
--- a/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
+++ b/third_party/blink/public/mojom/feature_policy/feature_policy.mojom
@@ -103,8 +103,6 @@
   kWakeLock = 31,
   // Controls access to font-display attribute in @font-face CSS rule
   kFontDisplay = 32,
-  // Sample Origin Trial enabled feature. This is used only for testing.
-  kFrobulate = 41,
 
   // These are the defined sandbox features implemented as policy-controlled
   // features.
@@ -118,6 +116,11 @@
   kPresentation = 40,
   // End of sandbox features.
 
+  // Sample Origin Trial enabled feature. This is used only for testing.
+  kFrobulate = 41,
+  // Controls access to Serial
+  kSerial = 42,
+
   // Don't change assigned numbers of any item, and don't reuse removed slots.
   // Also, run update_feature_policy_enum.py in
   // chromium/src/tools/metrics/histograms/ to update the UMA mapping.
diff --git a/third_party/blink/public/web/web_view_client.h b/third_party/blink/public/web/web_view_client.h
index 389a101..afa7c17 100644
--- a/third_party/blink/public/web/web_view_client.h
+++ b/third_party/blink/public/web/web_view_client.h
@@ -87,6 +87,12 @@
 
   // Misc ----------------------------------------------------------------
 
+  // Called when a region of the WebView needs to be re-painted. This is only
+  // for non-composited WebViews that exist to contribute to a "parent" WebView
+  // painting. Otherwise invalidations are transmitted to the compositor through
+  // the layers.
+  virtual void DidInvalidateRect(const WebRect&) {}
+
   // Called when script in the page calls window.print().  If frame is
   // non-null, then it selects a particular frame, including its
   // children, to print.  Otherwise, the main frame and its children
diff --git a/third_party/blink/public/web/web_widget.h b/third_party/blink/public/web/web_widget.h
index 8b5d4ef..4e67170f 100644
--- a/third_party/blink/public/web/web_widget.h
+++ b/third_party/blink/public/web/web_widget.h
@@ -120,7 +120,8 @@
 
   // Called to run through the entire set of document lifecycle phases needed
   // to render a frame of the web widget. This MUST be called before Paint,
-  // and it may result in calls to WebWidgetClient::DidInvalidateRect.
+  // and it may result in calls to WebViewClient::DidInvalidateRect (for
+  // non-composited WebViews).
   // |LifecycleUpdateReason| must be used to indicate the source of the
   // update for the purposes of metrics gathering.
   enum class LifecycleUpdate { kLayout, kPrePaint, kAll };
diff --git a/third_party/blink/public/web/web_widget_client.h b/third_party/blink/public/web/web_widget_client.h
index b19ca4cc..d9db9bc 100644
--- a/third_party/blink/public/web/web_widget_client.h
+++ b/third_party/blink/public/web/web_widget_client.h
@@ -64,9 +64,6 @@
  public:
   virtual ~WebWidgetClient() = default;
 
-  // Called when a region of the WebWidget needs to be re-painted.
-  virtual void DidInvalidateRect(const WebRect&) {}
-
   // Called to request a BeginMainFrame from the compositor. For tests with
   // single thread and no scheduler, the impl should schedule a task to run
   // a synchronous composite.
diff --git a/third_party/blink/renderer/bindings/scripts/v8_dictionary.py b/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
index 04860137..e06325a 100644
--- a/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
+++ b/third_party/blink/renderer/bindings/scripts/v8_dictionary.py
@@ -164,6 +164,7 @@
         'has_explicit_presence': has_explicit_presence,
         'has_method_name': has_method_name_for_dictionary_member(member),
         'idl_type': idl_type.base_type,
+        'is_callback_function_type': idl_type.is_callback_function,
         'is_interface_type': idl_type.is_interface_type and not is_deprecated_dictionary,
         'is_nullable': idl_type.is_nullable,
         'is_object': unwrapped_idl_type.name == 'Object' or is_deprecated_dictionary,
diff --git a/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl b/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl
index 5562da4..a3222727 100644
--- a/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl
+++ b/third_party/blink/renderer/bindings/templates/dictionary_v8.cc.tmpl
@@ -84,6 +84,12 @@
     {% if member.deprecate_as %}
     Deprecation::CountDeprecation(CurrentExecutionContext(isolate), WebFeature::k{{member.deprecate_as}});
     {% endif %}
+    {% if member.is_callback_function_type %}
+    if (!{{member.v8_value}}->IsFunction()) {
+      exception_state.ThrowTypeError("member {{member.name}} is not a function.");
+      return;
+    }
+    {% endif %}
     {{v8_value_to_local_cpp_value(member) | trim | indent}}
     {% if member.is_interface_type %}
     if (!{{member.cpp_value}}) {
diff --git a/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl b/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl
index 6166db7..baa9a92f 100644
--- a/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl
+++ b/third_party/blink/renderer/bindings/tests/idls/core/test_dictionary.idl
@@ -65,4 +65,5 @@
     VoidCallbackFunction callbackFunctionMember;
     required VoidCallbackFunction requiredCallbackFunctionMember;
     boolean member-with-hyphen-in-name = false;
+    TreatNonObjectAsNullVoidFunction treatNonNullObjMember;
 };
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
index e3589cf..52c3616 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.cc
@@ -166,6 +166,10 @@
   has_test_object_sequence_member_ = true;
 }
 
+void TestDictionary::setTreatNonNullObjMember(V8TreatNonObjectAsNullVoidFunction* value) {
+  treat_non_null_obj_member_ = value;
+}
+
 void TestDictionary::setTreatNullAsStringSequenceMember(const Vector<String>& value) {
   treat_null_as_string_sequence_member_ = value;
   has_treat_null_as_string_sequence_member_ = true;
@@ -219,6 +223,7 @@
   visitor->Trace(test_interface_or_null_member_);
   visitor->Trace(test_interface_sequence_member_);
   visitor->Trace(test_object_sequence_member_);
+  visitor->Trace(treat_non_null_obj_member_);
   visitor->Trace(uint8_array_member_);
   visitor->Trace(union_in_record_member_);
   visitor->Trace(union_member_with_sequence_default_);
diff --git a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h
index f175c03..7557e84 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h
+++ b/third_party/blink/renderer/bindings/tests/results/core/test_dictionary.h
@@ -23,6 +23,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/test_enum_or_test_enum_or_null_sequence.h"
 #include "third_party/blink/renderer/bindings/core/v8/test_enum_or_test_enum_sequence.h"
 #include "third_party/blink/renderer/bindings/core/v8/test_interface_2_or_uint8_array.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_treat_non_object_as_null_void_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_void_callback_function.h"
 #include "third_party/blink/renderer/bindings/tests/idls/core/test_interface_2.h"
 #include "third_party/blink/renderer/core/core_export.h"
@@ -381,6 +382,12 @@
   }
   void setTestObjectSequenceMember(const HeapVector<Member<TestObject>>&);
 
+  bool hasTreatNonNullObjMember() const { return treat_non_null_obj_member_; }
+  V8TreatNonObjectAsNullVoidFunction* treatNonNullObjMember() const {
+    return treat_non_null_obj_member_;
+  }
+  void setTreatNonNullObjMember(V8TreatNonObjectAsNullVoidFunction*);
+
   bool hasTreatNullAsStringSequenceMember() const { return has_treat_null_as_string_sequence_member_; }
   const Vector<String>& treatNullAsStringSequenceMember() const {
     DCHECK(has_treat_null_as_string_sequence_member_);
@@ -536,6 +543,7 @@
   Member<TestInterfaceImplementation> test_interface_or_null_member_;
   HeapVector<Member<TestInterfaceImplementation>> test_interface_sequence_member_;
   HeapVector<Member<TestObject>> test_object_sequence_member_;
+  TraceWrapperMember<V8TreatNonObjectAsNullVoidFunction> treat_non_null_obj_member_;
   Vector<String> treat_null_as_string_sequence_member_;
   Member<DOMUint8Array> uint8_array_member_;
   HeapVector<std::pair<String, LongOrBoolean>> union_in_record_member_;
diff --git a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
index dc39ee45..f0c425d 100644
--- a/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
+++ b/third_party/blink/renderer/bindings/tests/results/core/v8_test_dictionary.cc
@@ -22,6 +22,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_test_interface.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_test_interface_2.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_test_object.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_treat_non_object_as_null_void_function.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_uint8_array.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_void_callback_function.h"
 #include "third_party/blink/renderer/core/frame/deprecation.h"
@@ -86,6 +87,7 @@
     "testInterfaceOrNullMember",
     "testInterfaceSequenceMember",
     "testObjectSequenceMember",
+    "treatNonNullObjMember",
     "treatNullAsStringSequenceMember",
     "uint8ArrayMember",
     "unionInRecordMember",
@@ -194,6 +196,10 @@
   if (callback_function_member_value.IsEmpty() || callback_function_member_value->IsUndefined()) {
     // Do nothing.
   } else {
+    if (!callback_function_member_value->IsFunction()) {
+      exception_state.ThrowTypeError("member callbackFunctionMember is not a function.");
+      return;
+    }
     V8VoidCallbackFunction* callback_function_member_cpp_value = V8VoidCallbackFunction::Create(callback_function_member_value.As<v8::Function>());
     impl->setCallbackFunctionMember(callback_function_member_cpp_value);
   }
@@ -618,6 +624,10 @@
     exception_state.ThrowTypeError("required member requiredCallbackFunctionMember is undefined.");
     return;
   } else {
+    if (!required_callback_function_member_value->IsFunction()) {
+      exception_state.ThrowTypeError("member requiredCallbackFunctionMember is not a function.");
+      return;
+    }
     V8VoidCallbackFunction* required_callback_function_member_cpp_value = V8VoidCallbackFunction::Create(required_callback_function_member_value.As<v8::Function>());
     impl->setRequiredCallbackFunctionMember(required_callback_function_member_cpp_value);
   }
@@ -828,8 +838,24 @@
     impl->setTestObjectSequenceMember(test_object_sequence_member_cpp_value);
   }
 
+  v8::Local<v8::Value> treat_non_null_obj_member_value;
+  if (!v8Object->Get(context, keys[51].Get(isolate)).ToLocal(&treat_non_null_obj_member_value)) {
+    exception_state.RethrowV8Exception(block.Exception());
+    return;
+  }
+  if (treat_non_null_obj_member_value.IsEmpty() || treat_non_null_obj_member_value->IsUndefined()) {
+    // Do nothing.
+  } else {
+    if (!treat_non_null_obj_member_value->IsFunction()) {
+      exception_state.ThrowTypeError("member treatNonNullObjMember is not a function.");
+      return;
+    }
+    V8TreatNonObjectAsNullVoidFunction* treat_non_null_obj_member_cpp_value = V8TreatNonObjectAsNullVoidFunction::Create(treat_non_null_obj_member_value.As<v8::Function>());
+    impl->setTreatNonNullObjMember(treat_non_null_obj_member_cpp_value);
+  }
+
   v8::Local<v8::Value> treat_null_as_string_sequence_member_value;
-  if (!v8Object->Get(context, keys[51].Get(isolate)).ToLocal(&treat_null_as_string_sequence_member_value)) {
+  if (!v8Object->Get(context, keys[52].Get(isolate)).ToLocal(&treat_null_as_string_sequence_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -843,7 +869,7 @@
   }
 
   v8::Local<v8::Value> uint8_array_member_value;
-  if (!v8Object->Get(context, keys[52].Get(isolate)).ToLocal(&uint8_array_member_value)) {
+  if (!v8Object->Get(context, keys[53].Get(isolate)).ToLocal(&uint8_array_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -861,7 +887,7 @@
   }
 
   v8::Local<v8::Value> union_in_record_member_value;
-  if (!v8Object->Get(context, keys[53].Get(isolate)).ToLocal(&union_in_record_member_value)) {
+  if (!v8Object->Get(context, keys[54].Get(isolate)).ToLocal(&union_in_record_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -875,7 +901,7 @@
   }
 
   v8::Local<v8::Value> union_member_with_sequence_default_value;
-  if (!v8Object->Get(context, keys[54].Get(isolate)).ToLocal(&union_member_with_sequence_default_value)) {
+  if (!v8Object->Get(context, keys[55].Get(isolate)).ToLocal(&union_member_with_sequence_default_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -890,7 +916,7 @@
   }
 
   v8::Local<v8::Value> union_or_null_record_member_value;
-  if (!v8Object->Get(context, keys[55].Get(isolate)).ToLocal(&union_or_null_record_member_value)) {
+  if (!v8Object->Get(context, keys[56].Get(isolate)).ToLocal(&union_or_null_record_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -904,7 +930,7 @@
   }
 
   v8::Local<v8::Value> union_or_null_sequence_member_value;
-  if (!v8Object->Get(context, keys[56].Get(isolate)).ToLocal(&union_or_null_sequence_member_value)) {
+  if (!v8Object->Get(context, keys[57].Get(isolate)).ToLocal(&union_or_null_sequence_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -918,7 +944,7 @@
   }
 
   v8::Local<v8::Value> union_with_annotated_type_member_value;
-  if (!v8Object->Get(context, keys[57].Get(isolate)).ToLocal(&union_with_annotated_type_member_value)) {
+  if (!v8Object->Get(context, keys[58].Get(isolate)).ToLocal(&union_with_annotated_type_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -933,7 +959,7 @@
   }
 
   v8::Local<v8::Value> union_with_typedefs_value;
-  if (!v8Object->Get(context, keys[58].Get(isolate)).ToLocal(&union_with_typedefs_value)) {
+  if (!v8Object->Get(context, keys[59].Get(isolate)).ToLocal(&union_with_typedefs_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -948,7 +974,7 @@
   }
 
   v8::Local<v8::Value> unrestricted_double_member_value;
-  if (!v8Object->Get(context, keys[59].Get(isolate)).ToLocal(&unrestricted_double_member_value)) {
+  if (!v8Object->Get(context, keys[60].Get(isolate)).ToLocal(&unrestricted_double_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -962,7 +988,7 @@
   }
 
   v8::Local<v8::Value> usv_string_or_null_member_value;
-  if (!v8Object->Get(context, keys[60].Get(isolate)).ToLocal(&usv_string_or_null_member_value)) {
+  if (!v8Object->Get(context, keys[61].Get(isolate)).ToLocal(&usv_string_or_null_member_value)) {
     exception_state.RethrowV8Exception(block.Exception());
     return;
   }
@@ -1623,6 +1649,17 @@
     return false;
   }
 
+  v8::Local<v8::Value> treat_non_null_obj_member_value;
+  bool treat_non_null_obj_member_has_value_or_default = false;
+  if (impl->hasTreatNonNullObjMember()) {
+    treat_non_null_obj_member_value = ToV8(impl->treatNonNullObjMember(), creationContext, isolate);
+    treat_non_null_obj_member_has_value_or_default = true;
+  }
+  if (treat_non_null_obj_member_has_value_or_default &&
+      !create_property(51, treat_non_null_obj_member_value)) {
+    return false;
+  }
+
   v8::Local<v8::Value> treat_null_as_string_sequence_member_value;
   bool treat_null_as_string_sequence_member_has_value_or_default = false;
   if (impl->hasTreatNullAsStringSequenceMember()) {
@@ -1633,7 +1670,7 @@
     treat_null_as_string_sequence_member_has_value_or_default = true;
   }
   if (treat_null_as_string_sequence_member_has_value_or_default &&
-      !create_property(51, treat_null_as_string_sequence_member_value)) {
+      !create_property(52, treat_null_as_string_sequence_member_value)) {
     return false;
   }
 
@@ -1644,7 +1681,7 @@
     uint8_array_member_has_value_or_default = true;
   }
   if (uint8_array_member_has_value_or_default &&
-      !create_property(52, uint8_array_member_value)) {
+      !create_property(53, uint8_array_member_value)) {
     return false;
   }
 
@@ -1655,7 +1692,7 @@
     union_in_record_member_has_value_or_default = true;
   }
   if (union_in_record_member_has_value_or_default &&
-      !create_property(53, union_in_record_member_value)) {
+      !create_property(54, union_in_record_member_value)) {
     return false;
   }
 
@@ -1669,7 +1706,7 @@
     union_member_with_sequence_default_has_value_or_default = true;
   }
   if (union_member_with_sequence_default_has_value_or_default &&
-      !create_property(54, union_member_with_sequence_default_value)) {
+      !create_property(55, union_member_with_sequence_default_value)) {
     return false;
   }
 
@@ -1680,7 +1717,7 @@
     union_or_null_record_member_has_value_or_default = true;
   }
   if (union_or_null_record_member_has_value_or_default &&
-      !create_property(55, union_or_null_record_member_value)) {
+      !create_property(56, union_or_null_record_member_value)) {
     return false;
   }
 
@@ -1691,7 +1728,7 @@
     union_or_null_sequence_member_has_value_or_default = true;
   }
   if (union_or_null_sequence_member_has_value_or_default &&
-      !create_property(56, union_or_null_sequence_member_value)) {
+      !create_property(57, union_or_null_sequence_member_value)) {
     return false;
   }
 
@@ -1702,7 +1739,7 @@
     union_with_annotated_type_member_has_value_or_default = true;
   }
   if (union_with_annotated_type_member_has_value_or_default &&
-      !create_property(57, union_with_annotated_type_member_value)) {
+      !create_property(58, union_with_annotated_type_member_value)) {
     return false;
   }
 
@@ -1713,7 +1750,7 @@
     union_with_typedefs_has_value_or_default = true;
   }
   if (union_with_typedefs_has_value_or_default &&
-      !create_property(58, union_with_typedefs_value)) {
+      !create_property(59, union_with_typedefs_value)) {
     return false;
   }
 
@@ -1727,7 +1764,7 @@
     unrestricted_double_member_has_value_or_default = true;
   }
   if (unrestricted_double_member_has_value_or_default &&
-      !create_property(59, unrestricted_double_member_value)) {
+      !create_property(60, unrestricted_double_member_value)) {
     return false;
   }
 
@@ -1741,7 +1778,7 @@
     usv_string_or_null_member_has_value_or_default = true;
   }
   if (usv_string_or_null_member_has_value_or_default &&
-      !create_property(60, usv_string_or_null_member_value)) {
+      !create_property(61, usv_string_or_null_member_value)) {
     return false;
   }
 
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 52401bba..920f6681 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -5473,29 +5473,22 @@
     return;
   }
 
-  // TODO(mkwst): If we decide to ship this, change the IDL file to make the
-  // value nullable (via `TreatNullAs=NullString`, for example). For the moment,
-  // just rely on JavaScript's inherent nuttiness for implicit conversion to the
-  // string "null". https://crbug.com/733150
-  if (!RuntimeEnabledFeatures::NullableDocumentDomainEnabled() ||
-      new_domain != "null") {
-    OriginAccessEntry access_entry(
-        GetSecurityOrigin()->Protocol(), new_domain,
-        network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains);
-    network::cors::OriginAccessEntry::MatchResult result =
-        access_entry.MatchesOrigin(*GetSecurityOrigin());
-    if (result == network::cors::OriginAccessEntry::kDoesNotMatchOrigin) {
-      exception_state.ThrowSecurityError(
-          "'" + new_domain + "' is not a suffix of '" + domain() + "'.");
-      return;
-    }
+  OriginAccessEntry access_entry(
+      GetSecurityOrigin()->Protocol(), new_domain,
+      network::mojom::CorsOriginAccessMatchMode::kAllowSubdomains);
+  network::cors::OriginAccessEntry::MatchResult result =
+      access_entry.MatchesOrigin(*GetSecurityOrigin());
+  if (result == network::cors::OriginAccessEntry::kDoesNotMatchOrigin) {
+    exception_state.ThrowSecurityError(
+        "'" + new_domain + "' is not a suffix of '" + domain() + "'.");
+    return;
+  }
 
-    if (result ==
-        network::cors::OriginAccessEntry::kMatchesOriginButIsPublicSuffix) {
-      exception_state.ThrowSecurityError("'" + new_domain +
-                                         "' is a top-level domain.");
-      return;
-    }
+  if (result ==
+      network::cors::OriginAccessEntry::kMatchesOriginButIsPublicSuffix) {
+    exception_state.ThrowSecurityError("'" + new_domain +
+                                       "' is a top-level domain.");
+    return;
   }
 
   if (frame_) {
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
index 8b968dd..5af2778d 100644
--- a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
+++ b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.cc
@@ -57,7 +57,7 @@
 }
 
 void MarkupAccumulator::AppendEndTag(const Element& element) {
-  AppendEndMarkup(element);
+  formatter_.AppendEndMarkup(markup_, element);
 }
 
 void MarkupAccumulator::AppendStartMarkup(const Node& node) {
@@ -66,7 +66,7 @@
       formatter_.AppendText(markup_, ToText(node));
       break;
     case Node::kElementNode:
-      AppendElement(ToElement(node));
+      NOTREACHED();
       break;
     case Node::kAttributeNode:
       // Only XMLSerializer can pass an Attr.  So, |documentIsHTML| flag is
@@ -79,10 +79,6 @@
   }
 }
 
-void MarkupAccumulator::AppendEndMarkup(const Element& element) {
-  formatter_.AppendEndMarkup(markup_, element);
-}
-
 void MarkupAccumulator::AppendCustomAttributes(const Element&) {}
 
 bool MarkupAccumulator::ShouldIgnoreAttribute(
@@ -239,8 +235,8 @@
   return formatter_.EntityMaskForText(text);
 }
 
-void MarkupAccumulator::PushNamespaces(const Node& node) {
-  if (!node.IsElementNode() || SerializeAsHTMLDocument(node))
+void MarkupAccumulator::PushNamespaces(const Element& element) {
+  if (SerializeAsHTMLDocument(element))
     return;
   DCHECK_GT(namespace_stack_.size(), 0u);
   // TODO(tkent): Avoid to copy the whole map.
@@ -250,8 +246,8 @@
   namespace_stack_.push_back(Namespaces(namespace_stack_.back()));
 }
 
-void MarkupAccumulator::PopNamespaces(const Node& node) {
-  if (!node.IsElementNode() || SerializeAsHTMLDocument(node))
+void MarkupAccumulator::PopNamespaces(const Element& element) {
+  if (SerializeAsHTMLDocument(element))
     return;
   namespace_stack_.pop_back();
 }
@@ -310,49 +306,50 @@
 void MarkupAccumulator::SerializeNodesWithNamespaces(
     const Node& target_node,
     EChildrenOnly children_only) {
-  if (target_node.IsElementNode() &&
-      ShouldIgnoreElement(ToElement(target_node))) {
+  if (!target_node.IsElementNode()) {
+    if (!children_only)
+      AppendStartMarkup(target_node);
+    for (const Node& child : Strategy::ChildrenOf(target_node))
+      SerializeNodesWithNamespaces<Strategy>(child, kIncludeNode);
     return;
   }
 
-  PushNamespaces(target_node);
+  const Element& target_element = ToElement(target_node);
+  if (ShouldIgnoreElement(target_element))
+    return;
+
+  PushNamespaces(target_element);
 
   if (!children_only)
-    AppendStartMarkup(target_node);
+    AppendElement(target_element);
 
-  if (!(SerializeAsHTMLDocument(target_node) &&
-        ElementCannotHaveEndTag(target_node))) {
-    Node* current = IsHTMLTemplateElement(target_node)
-                        ? Strategy::FirstChild(
-                              *ToHTMLTemplateElement(target_node).content())
-                        : Strategy::FirstChild(target_node);
-    for (; current; current = Strategy::NextSibling(*current))
-      SerializeNodesWithNamespaces<Strategy>(*current, kIncludeNode);
+  bool has_end_tag = !(SerializeAsHTMLDocument(target_element) &&
+                       ElementCannotHaveEndTag(target_element));
+  if (has_end_tag) {
+    const Node* parent = &target_element;
+    if (auto* template_element = ToHTMLTemplateElementOrNull(target_element))
+      parent = template_element->content();
+    for (const Node& child : Strategy::ChildrenOf(*parent))
+      SerializeNodesWithNamespaces<Strategy>(child, kIncludeNode);
 
     // Traverses other DOM tree, i.e., shadow tree.
-    if (target_node.IsElementNode()) {
-      std::pair<Node*, Element*> auxiliary_pair =
-          GetAuxiliaryDOMTree(ToElement(target_node));
-      Node* auxiliary_tree = auxiliary_pair.first;
-      Element* enclosing_element = auxiliary_pair.second;
-      if (auxiliary_tree) {
-        if (auxiliary_pair.second)
-          AppendStartMarkup(*enclosing_element);
-        current = Strategy::FirstChild(*auxiliary_tree);
-        for (; current; current = Strategy::NextSibling(*current)) {
-          SerializeNodesWithNamespaces<Strategy>(*current, kIncludeNode);
-        }
-        if (enclosing_element)
-          AppendEndTag(*enclosing_element);
-      }
+    std::pair<Node*, Element*> auxiliary_pair =
+        GetAuxiliaryDOMTree(target_element);
+    Node* auxiliary_tree = auxiliary_pair.first;
+    Element* enclosing_element = auxiliary_pair.second;
+    if (auxiliary_tree) {
+      if (auxiliary_pair.second)
+        AppendElement(*enclosing_element);
+      for (const Node& child : Strategy::ChildrenOf(*auxiliary_tree))
+        SerializeNodesWithNamespaces<Strategy>(child, kIncludeNode);
+      if (enclosing_element)
+        AppendEndTag(*enclosing_element);
     }
   }
 
-  if ((!children_only && target_node.IsElementNode()) &&
-      !(SerializeAsHTMLDocument(target_node) &&
-        ElementCannotHaveEndTag(target_node)))
-    AppendEndTag(ToElement(target_node));
-  PopNamespaces(target_node);
+  if (!children_only && has_end_tag)
+    AppendEndTag(target_element);
+  PopNamespaces(target_element);
 }
 
 template <typename Strategy>
diff --git a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h
index 170f023..e78fc05 100644
--- a/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h
+++ b/third_party/blink/renderer/core/editing/serializers/markup_accumulator.h
@@ -27,6 +27,8 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SERIALIZERS_MARKUP_ACCUMULATOR_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_SERIALIZERS_MARKUP_ACCUMULATOR_H_
 
+#include <utility>
+
 #include "base/macros.h"
 #include "third_party/blink/renderer/core/editing/editing_strategy.h"
 #include "third_party/blink/renderer/core/editing/serializers/markup_formatter.h"
@@ -54,8 +56,6 @@
   String SerializeNodes(const Node&, EChildrenOnly);
 
  protected:
-  // Serialize a Node, without its children and its end tag.
-  virtual void AppendStartMarkup(const Node&);
   virtual void AppendElement(const Element&);
   virtual void AppendAttribute(const Element&, const Attribute&);
 
@@ -67,6 +67,8 @@
   String ToString() { return markup_.ToString(); }
 
   void AppendString(const String&);
+  // Serialize a Node, without its children and its end tag.
+  void AppendStartMarkup(const Node&);
   void AppendStartTagOpen(const Element&);
   void AppendStartTagClose(const Element&);
   bool ShouldAddNamespaceElement(const Element&);
@@ -79,12 +81,11 @@
                                           const Element& element);
 
   void AppendEndTag(const Element&);
-  void AppendEndMarkup(const Element&);
 
   EntityMask EntityMaskForText(const Text&) const;
 
-  void PushNamespaces(const Node& node);
-  void PopNamespaces(const Node& node);
+  void PushNamespaces(const Element& element);
+  void PopNamespaces(const Element& element);
   void AddPrefix(const AtomicString& prefix, const AtomicString& namespace_uri);
   AtomicString LookupNamespaceURI(const AtomicString& prefix);
   AtomicString GeneratePrefix(const AtomicString& new_namespace);
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 581cbd6..50746d2 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
@@ -124,11 +124,6 @@
 #endif
   }
 
-  void InvalidateRect(const IntRect& paint_rect) override {
-    if (!paint_rect.IsEmpty())
-      popup_->WidgetClient()->DidInvalidateRect(paint_rect);
-  }
-
   void ScheduleAnimation(const LocalFrameView*) override {
     if (WebTestSupport::IsRunningWebTest()) {
       // In single threaded web tests, the main frame's WebWidgetClient
@@ -435,9 +430,6 @@
     MainFrame().View()->Resize(new_size_in_viewport);
     page_->GetVisualViewport().SetSize(new_size_in_viewport);
   }
-
-  widget_client_->DidInvalidateRect(
-      WebRect(0, 0, new_size.width, new_size.height));
 }
 
 WebInputEventResult WebPagePopupImpl::HandleKeyEvent(
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 77be24a..9841972 100644
--- a/third_party/blink/renderer/core/exported/web_view_impl.cc
+++ b/third_party/blink/renderer/core/exported/web_view_impl.cc
@@ -3239,8 +3239,8 @@
 
 void WebViewImpl::InvalidateRect(const IntRect& rect) {
   // This is only for WebViewPlugin.
-  if (!does_composite_ && AsWidget().client)
-    AsWidget().client->DidInvalidateRect(rect);
+  if (!does_composite_ && AsView().client)
+    AsView().client->DidInvalidateRect(rect);
 }
 
 PaintLayerCompositor* WebViewImpl::Compositor() const {
diff --git a/third_party/blink/renderer/core/feature_policy/feature_policy.cc b/third_party/blink/renderer/core/feature_policy/feature_policy.cc
index 0fb344f..8a88251 100644
--- a/third_party/blink/renderer/core/feature_policy/feature_policy.cc
+++ b/third_party/blink/renderer/core/feature_policy/feature_policy.cc
@@ -358,6 +358,10 @@
       default_feature_name_map.Set("magnetometer",
                                    mojom::FeaturePolicyFeature::kMagnetometer);
     }
+    if (RuntimeEnabledFeatures::SerialEnabled()) {
+      default_feature_name_map.Set("serial",
+                                   mojom::FeaturePolicyFeature::kSerial);
+    }
     if (RuntimeEnabledFeatures::WakeLockEnabled()) {
       default_feature_name_map.Set("wake-lock",
                                    mojom::FeaturePolicyFeature::kWakeLock);
diff --git a/third_party/blink/renderer/core/frame/frame_serializer.cc b/third_party/blink/renderer/core/frame/frame_serializer.cc
index 3fe5007..2f4ef44 100644
--- a/third_party/blink/renderer/core/frame/frame_serializer.cc
+++ b/third_party/blink/renderer/core/frame/frame_serializer.cc
@@ -85,7 +85,7 @@
  public:
   SerializerMarkupAccumulator(FrameSerializer::Delegate&,
                               const Document&,
-                              HeapVector<Member<const Node>>&);
+                              HeapVector<Member<const Element>>&);
   ~SerializerMarkupAccumulator() override;
 
  protected:
@@ -94,7 +94,6 @@
   bool ShouldIgnoreElement(const Element&) const override;
   void AppendElement(const Element&) override;
   void AppendAttribute(const Element&, const Attribute&) override;
-  void AppendStartMarkup(const Node&) override;
   std::pair<Node*, Element*> GetAuxiliaryDOMTree(const Element&) const override;
 
  private:
@@ -106,11 +105,11 @@
   FrameSerializer::Delegate& delegate_;
   Member<const Document> document_;
 
-  // FIXME: |FrameSerializer| uses |m_nodes| for collecting nodes in document
-  // included into serialized text then extracts image, object, etc. The size
-  // of this vector isn't small for large document. It is better to use
+  // FIXME: |FrameSerializer| uses |elements_| for collecting elements in
+  // document included into serialized text then extracts image, object, etc.
+  // The size of this vector isn't small for large document. It is better to use
   // callback like functionality.
-  HeapVector<Member<const Node>>& nodes_;
+  HeapVector<Member<const Element>>& elements_;
 
   // Elements with links rewritten via appendAttribute method.
   HeapHashSet<Member<const Element>> elements_with_rewritten_links_;
@@ -119,11 +118,11 @@
 SerializerMarkupAccumulator::SerializerMarkupAccumulator(
     FrameSerializer::Delegate& delegate,
     const Document& document,
-    HeapVector<Member<const Node>>& nodes)
+    HeapVector<Member<const Element>>& elements)
     : MarkupAccumulator(kResolveAllURLs),
       delegate_(delegate),
       document_(&document),
-      nodes_(nodes) {}
+      elements_(elements) {}
 
 SerializerMarkupAccumulator::~SerializerMarkupAccumulator() = default;
 
@@ -168,6 +167,7 @@
     else
       markup_.Append("\">");
   }
+  elements_.push_back(&element);
 
   // FIXME: For object (plugins) tags and video tag we could replace them by an
   // image of their current contents.
@@ -204,11 +204,6 @@
   MarkupAccumulator::AppendAttribute(element, attribute);
 }
 
-void SerializerMarkupAccumulator::AppendStartMarkup(const Node& node) {
-  MarkupAccumulator::AppendStartMarkup(node);
-  nodes_.push_back(&node);
-}
-
 std::pair<Node*, Element*> SerializerMarkupAccumulator::GetAuxiliaryDOMTree(
     const Element& element) const {
   return delegate_.GetAuxiliaryDOMTree(element);
@@ -269,13 +264,13 @@
     return;
   }
 
-  HeapVector<Member<const Node>> serialized_nodes;
+  HeapVector<Member<const Element>> serialized_elements;
   {
     TRACE_EVENT0("page-serialization", "FrameSerializer::serializeFrame HTML");
     SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
         "PageSerialization.SerializationTime.Html");
     SerializerMarkupAccumulator accumulator(delegate_, document,
-                                            serialized_nodes);
+                                            serialized_elements);
     String text =
         accumulator.SerializeNodes<EditingStrategy>(document, kIncludeNode);
 
@@ -288,12 +283,9 @@
 
   should_collect_problem_metric_ =
       delegate_.ShouldCollectProblemMetric() && frame.IsMainFrame();
-  for (const Node* node : serialized_nodes) {
+  for (const Element* node : serialized_elements) {
     DCHECK(node);
-    if (!node->IsElementNode())
-      continue;
-
-    const Element& element = ToElement(*node);
+    const Element& element = *node;
     // We have to process in-line style as it might contain some resources
     // (typically background images).
     if (element.IsStyledElement()) {
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 f96299a..526c8d9 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
@@ -238,13 +238,7 @@
     LocalRootImpl()->GetFrame()->GetDocument()->EnqueueResizeEvent();
   }
 
-  DCHECK(Client());
-  if (IsAcceleratedCompositingActive()) {
-    UpdateLayerTreeViewport();
-  } else {
-    WebRect damaged_rect(0, 0, size_->width, size_->height);
-    Client()->DidInvalidateRect(damaged_rect);
-  }
+  UpdateLayerTreeViewport();
 }
 
 void WebFrameWidgetImpl::ResizeVisualViewport(const WebSize& new_size) {
diff --git a/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js b/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js
index d4b6856..b5071055 100644
--- a/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js
+++ b/third_party/blink/renderer/core/html/forms/resources/pickerCommon.js
@@ -141,7 +141,14 @@
 
   var availableSpaceBelow = availRect.maxY - anchorRect.maxY;
   availableSpaceBelow = Math.max(0, Math.min(availRect.height, availableSpaceBelow));
-  if (windowRect.height > availableSpaceBelow && availableSpaceBelow < availableSpaceAbove) {
+
+  // In some situations, there may be no space available.  This can happen on
+  // Linux when using a buggy window manager (https://crbug.com/774232).  When
+  // this happens, don't try to constrain the window at all.
+  if (availableSpaceAbove == 0 && availableSpaceBelow == 0) {
+    windowRect.height = Math.max(minHeight, windowRect.height);
+    windowRect.y = anchorRect.maxY;
+  } else if (windowRect.height > availableSpaceBelow && availableSpaceBelow < availableSpaceAbove) {
     windowRect.height = Math.min(windowRect.height, availableSpaceAbove);
     windowRect.height = Math.max(windowRect.height, minHeight);
     windowRect.y = anchorRect.y - windowRect.height;
@@ -156,6 +163,11 @@
  * Arguments are DIPs.
  */
 function _adjustWindowRectHorizontally(windowRect, availRect, anchorRect, minWidth) {
+  if (anchorRect.maxX <= availRect.x || availRect.maxX <= anchorRect.x) {
+    windowRect.width = Math.max(minWidth, windowRect.width);
+    windowRect.x = anchorRect.x
+    return;
+  }
   windowRect.width = Math.min(windowRect.width, availRect.width);
   windowRect.width = Math.max(windowRect.width, minWidth);
   windowRect.x = anchorRect.x;
diff --git a/third_party/blink/renderer/core/inspector/browser_protocol.pdl b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
index 8437a38..7986125 100644
--- a/third_party/blink/renderer/core/inspector/browser_protocol.pdl
+++ b/third_party/blink/renderer/core/inspector/browser_protocol.pdl
@@ -538,6 +538,9 @@
   # Crashes browser on the main thread.
   experimental command crash
 
+  # Crashes GPU process.
+  experimental command crashGpuProcess
+
   # Returns version information.
   command getVersion
     returns
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 3ef1134..ac4295f5 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1869,7 +1869,15 @@
 #endif  // NDEBUG
 
 bool LayoutObject::IsSelected() const {
-  return LayoutSelection::IsSelected(*this);
+  // Keep this fast and small, used in very hot functions to skip computing
+  // selection when this is not selected. This function may be inlined in
+  // link-optimized builds, but keeping fast and small helps running perf
+  // tests.
+  return GetSelectionState() != SelectionState::kNone ||
+         // TODO(kojii): Can't we set SelectionState() properly to
+         // LayoutTextFragment too?
+         (IsText() && ToLayoutText(*this).IsTextFragment() &&
+          LayoutSelection::IsSelected(*this));
 }
 
 bool LayoutObject::IsSelectable() const {
diff --git a/third_party/blink/renderer/core/layout/layout_text.cc b/third_party/blink/renderer/core/layout/layout_text.cc
index 2497e88..b5d116d5 100644
--- a/third_party/blink/renderer/core/layout/layout_text.cc
+++ b/third_party/blink/renderer/core/layout/layout_text.cc
@@ -129,6 +129,7 @@
       known_to_have_no_overflow_and_no_fallback_fonts_(false),
       contains_only_whitespace_or_nbsp_(
           static_cast<unsigned>(OnlyWhitespaceOrNbsp::kUnknown)),
+      is_text_fragment_(false),
       has_abstract_inline_text_box_(false),
       min_width_(-1),
       max_width_(-1),
@@ -166,10 +167,6 @@
   return text;
 }
 
-bool LayoutText::IsTextFragment() const {
-  return false;
-}
-
 bool LayoutText::IsWordBreak() const {
   return false;
 }
@@ -2055,14 +2052,9 @@
 LayoutRect LayoutText::VisualOverflowRect() const {
   if (IsInLayoutNGInlineFormattingContext()) {
     LayoutRect rect;
-    auto fragments = NGPaintFragment::InlineFragmentsFor(this);
-    for (const NGPaintFragment* fragment : fragments) {
-      LayoutRect child_rect = fragment->VisualRect();
-      child_rect.MoveBy(fragment->InlineOffsetToContainerBox().ToLayoutPoint());
-      rect.Unite(child_rect);
-    }
-    ContainingBlock()->FlipForWritingMode(rect);
-    return rect;
+    if (NGPaintFragment::FlippedLocalVisualRectFor(this, &rect))
+      return rect;
+    NOTREACHED();
   }
 
   if (!FirstTextBox())
@@ -2110,12 +2102,15 @@
 }
 
 LayoutRect LayoutText::LocalVisualRectIgnoringVisibility() const {
-  if (RuntimeEnabledFeatures::LayoutNGEnabled()) {
-    LayoutRect visual_rect;
-    if (NGPaintFragment::FlippedLocalVisualRectFor(this, &visual_rect))
-      return visual_rect;
+  if (IsInLayoutNGInlineFormattingContext()) {
+    LayoutRect rect;
+    if (NGPaintFragment::FlippedLocalVisualRectFor(this, &rect)) {
+      if (!IsSelected())
+        return rect;
+      return UnionRect(rect, LocalSelectionRect());
+    }
+    NOTREACHED();
   }
-
   return UnionRect(VisualOverflowRect(), LocalSelectionRect());
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_text.h b/third_party/blink/renderer/core/layout/layout_text.h
index cfefdc2..3f270192 100644
--- a/third_party/blink/renderer/core/layout/layout_text.h
+++ b/third_party/blink/renderer/core/layout/layout_text.h
@@ -86,7 +86,7 @@
 
   const char* GetName() const override { return "LayoutText"; }
 
-  virtual bool IsTextFragment() const;
+  bool IsTextFragment() const { return is_text_fragment_; }
   virtual bool IsWordBreak() const;
 
   virtual scoped_refptr<StringImpl> OriginalText() const;
@@ -428,6 +428,8 @@
   mutable unsigned known_to_have_no_overflow_and_no_fallback_fonts_ : 1;
   unsigned contains_only_whitespace_or_nbsp_ : 2;
 
+  unsigned is_text_fragment_ : 1;
+
  private:
   // Used for LayoutNG with accessibility. True if inline fragments are
   // associated to |NGAbstractInlineTextBox|.
diff --git a/third_party/blink/renderer/core/layout/layout_text_fragment.cc b/third_party/blink/renderer/core/layout/layout_text_fragment.cc
index 563fe6f..3c629a7 100644
--- a/third_party/blink/renderer/core/layout/layout_text_fragment.cc
+++ b/third_party/blink/renderer/core/layout/layout_text_fragment.cc
@@ -42,7 +42,9 @@
       fragment_length_(length),
       is_remaining_text_layout_object_(false),
       content_string_(str),
-      first_letter_pseudo_element_(nullptr) {}
+      first_letter_pseudo_element_(nullptr) {
+  is_text_fragment_ = true;
+}
 
 LayoutTextFragment::~LayoutTextFragment() {
   DCHECK(!first_letter_pseudo_element_);
diff --git a/third_party/blink/renderer/core/layout/layout_text_fragment.h b/third_party/blink/renderer/core/layout/layout_text_fragment.h
index 8f3cc214..70d46ca 100644
--- a/third_party/blink/renderer/core/layout/layout_text_fragment.h
+++ b/third_party/blink/renderer/core/layout/layout_text_fragment.h
@@ -56,8 +56,6 @@
                                              unsigned start,
                                              unsigned length);
 
-  bool IsTextFragment() const override { return true; }
-
   Position PositionForCaretOffset(unsigned) const override;
   base::Optional<unsigned> CaretOffsetForPosition(
       const Position&) const override;
diff --git a/third_party/blink/renderer/core/page/chrome_client.h b/third_party/blink/renderer/core/page/chrome_client.h
index 262a76b..4b21628 100644
--- a/third_party/blink/renderer/core/page/chrome_client.h
+++ b/third_party/blink/renderer/core/page/chrome_client.h
@@ -110,7 +110,8 @@
 
   virtual void ChromeDestroyed() = 0;
 
-  // Requests the host invalidate the contents.
+  // For non-composited WebViews that exist to contribute to a "parent" WebView
+  // painting. This informs the client of the area that needs to be redrawn.
   virtual void InvalidateRect(const IntRect& update_rect) = 0;
 
   // Converts the rect from the viewport coordinates to screen coordinates.
diff --git a/third_party/blink/renderer/core/workers/dedicated_worker.h b/third_party/blink/renderer/core/workers/dedicated_worker.h
index 0a17083..a1774b3 100644
--- a/third_party/blink/renderer/core/workers/dedicated_worker.h
+++ b/third_party/blink/renderer/core/workers/dedicated_worker.h
@@ -36,7 +36,9 @@
 // https://html.spec.whatwg.org/multipage/workers.html#worker
 //
 // Confusingly, the Worker interface is for dedicated workers, so this class is
-// called DedicatedWorker. This lives on the main thread.
+// called DedicatedWorker. This lives on the thread that created the worker (the
+// thread that called `new Worker()`), i.e., the main thread if a document
+// created the worker or a worker thread in the case of nested workers.
 class CORE_EXPORT DedicatedWorker final
     : public AbstractWorker,
       public ActiveScriptWrappable<DedicatedWorker> {
diff --git a/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js b/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js
index 8df7376..7833a9d 100644
--- a/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js
+++ b/third_party/blink/renderer/devtools/front_end/sdk/OverlayModel.js
@@ -195,6 +195,10 @@
   highlightFrame(frameId) {
     if (SDK.OverlayModel._highlightDisabled)
       return;
+    if (this._hideHighlightTimeout) {
+      clearTimeout(this._hideHighlightTimeout);
+      this._hideHighlightTimeout = null;
+    }
     this._highlighter.highlightFrame(frameId);
   }
 
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.cc b/third_party/blink/renderer/modules/clipboard/clipboard.cc
index f0ced28..fa4c735 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard.cc
@@ -20,11 +20,7 @@
   return ClipboardPromise::CreateForReadText(script_state);
 }
 
-ScriptPromise Clipboard::readImageExperimental(ScriptState* script_state) {
-  return ClipboardPromise::CreateForReadImage(script_state);
-}
-
-ScriptPromise Clipboard::write(ScriptState* script_state, DataTransfer* data) {
+ScriptPromise Clipboard::write(ScriptState* script_state, Blob* data) {
   return ClipboardPromise::CreateForWrite(script_state, data);
 }
 
@@ -33,11 +29,6 @@
   return ClipboardPromise::CreateForWriteText(script_state, data);
 }
 
-ScriptPromise Clipboard::writeImageExperimental(ScriptState* script_state,
-                                                Blob* data) {
-  return ClipboardPromise::CreateForWriteImage(script_state, data);
-}
-
 const AtomicString& Clipboard::InterfaceName() const {
   return event_target_names::kClipboard;
 }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.h b/third_party/blink/renderer/modules/clipboard/clipboard.h
index ae9789e8f..316671da 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard.h
@@ -13,7 +13,6 @@
 
 namespace blink {
 
-class DataTransfer;
 class ScriptState;
 
 class Clipboard : public EventTargetWithInlineData,
@@ -27,11 +26,9 @@
 
   ScriptPromise read(ScriptState*);
   ScriptPromise readText(ScriptState*);
-  ScriptPromise readImageExperimental(ScriptState*);
 
-  ScriptPromise write(ScriptState*, DataTransfer*);
+  ScriptPromise write(ScriptState*, Blob*);
   ScriptPromise writeText(ScriptState*, const String&);
-  ScriptPromise writeImageExperimental(ScriptState*, Blob*);
 
   // EventTarget
   const AtomicString& InterfaceName() const override;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard.idl b/third_party/blink/renderer/modules/clipboard/clipboard.idl
index 0aa39d8..dfe2c09 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard.idl
+++ b/third_party/blink/renderer/modules/clipboard/clipboard.idl
@@ -11,29 +11,19 @@
     [MeasureAs=AsyncClipboardAPIRead,
      CallWith=ScriptState,
      RuntimeEnabled=AsyncClipboard
-    ] Promise<DataTransfer> read();
+    ] Promise<Blob> read();
 
     [MeasureAs=AsyncClipboardAPIReadText,
      CallWith=ScriptState
     ] Promise<DOMString> readText();
 
-    [
-     CallWith=ScriptState,
-     RuntimeEnabled=AsyncClipboardImages
-    ] Promise<Blob> readImageExperimental();
-
 
     [MeasureAs=AsyncClipboardAPIWrite,
      CallWith=ScriptState,
      RuntimeEnabled=AsyncClipboard
-    ] Promise<void> write(DataTransfer data);
+    ] Promise<void> write(Blob data);
 
     [MeasureAs=AsyncClipboardAPIWriteText,
      CallWith=ScriptState
     ] Promise<void> writeText(DOMString data);
-
-    [
-     CallWith=ScriptState,
-     RuntimeEnabled=AsyncClipboardImages
-    ] Promise<void> writeImageExperimental(Blob data);
 };
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc
index e752e1ab4..f8bdae04 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.cc
@@ -28,7 +28,7 @@
 // FileReaderLoaderClient implementation.
 void ClipboardFileReader::DidFinishLoading() {
   DOMArrayBuffer* array_buffer = loader_->ArrayBufferResult();
-  promise_->OnLoadComplete(array_buffer);
+  promise_->OnLoadBufferComplete(array_buffer);
 }
 
 void ClipboardFileReader::DidFail(FileErrorCode error_code) {
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h
index 11fc3fd..93b9814c 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_file_reader.h
@@ -20,10 +20,6 @@
 //
 // Created for the intent of use with clipboard, but may be generic enough for
 // other uses.
-//
-// TODO (crbug.com/916821): This class is very similar to ImageBitmapFactories::
-// ImageBitmapLoader. Ask ImageBitmapLoader creators if there's potential to
-// merge code and reduce duplicate code.
 class ClipboardFileReader final : public FileReaderLoaderClient {
  public:
   ClipboardFileReader(Blob*,
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
index 6dbfabfc..de0e7bfb 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/clipboard/clipboard_promise.h"
 
+#include <memory>
 #include "base/single_thread_task_runner.h"
 #include "base/task/post_task.h"
 #include "third_party/blink/public/platform/modules/permissions/permission.mojom-blink.h"
@@ -11,11 +12,6 @@
 #include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
 #include "third_party/blink/renderer/core/clipboard/clipboard_mime_types.h"
-#include "third_party/blink/renderer/core/clipboard/data_object.h"
-#include "third_party/blink/renderer/core/clipboard/data_transfer.h"
-#include "third_party/blink/renderer/core/clipboard/data_transfer_access_policy.h"
-#include "third_party/blink/renderer/core/clipboard/data_transfer_item.h"
-#include "third_party/blink/renderer/core/clipboard/data_transfer_item_list.h"
 #include "third_party/blink/renderer/core/clipboard/system_clipboard.h"
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
@@ -67,17 +63,8 @@
   return clipboard_promise->script_promise_resolver_->Promise();
 }
 
-ScriptPromise ClipboardPromise::CreateForReadImage(ScriptState* script_state) {
-  ClipboardPromise* clipboard_promise =
-      MakeGarbageCollected<ClipboardPromise>(script_state);
-  clipboard_promise->GetTaskRunner()->PostTask(
-      FROM_HERE, WTF::Bind(&ClipboardPromise::HandleReadImage,
-                           WrapPersistent(clipboard_promise)));
-  return clipboard_promise->script_promise_resolver_->Promise();
-}
-
 ScriptPromise ClipboardPromise::CreateForWrite(ScriptState* script_state,
-                                               DataTransfer* data) {
+                                               Blob* data) {
   ClipboardPromise* clipboard_promise =
       MakeGarbageCollected<ClipboardPromise>(script_state);
   clipboard_promise->GetTaskRunner()->PostTask(
@@ -97,17 +84,6 @@
   return clipboard_promise->script_promise_resolver_->Promise();
 }
 
-ScriptPromise ClipboardPromise::CreateForWriteImage(ScriptState* script_state,
-                                                    Blob* data) {
-  ClipboardPromise* clipboard_promise =
-      MakeGarbageCollected<ClipboardPromise>(script_state);
-  clipboard_promise->GetTaskRunner()->PostTask(
-      FROM_HERE,
-      WTF::Bind(&ClipboardPromise::HandleWriteImage,
-                WrapPersistent(clipboard_promise), WrapPersistent(data)));
-  return clipboard_promise->script_promise_resolver_->Promise();
-}
-
 ClipboardPromise::ClipboardPromise(ScriptState* script_state)
     : ContextLifecycleObserver(blink::ExecutionContext::From(script_state)),
       script_state_(script_state),
@@ -117,11 +93,13 @@
           GetExecutionContext()->GetTaskRunner(TaskType::kFileReading)) {}
 
 scoped_refptr<base::SingleThreadTaskRunner> ClipboardPromise::GetTaskRunner() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   // TODO(garykac): Replace MiscPlatformAPI with TaskType specific to clipboard.
   return GetExecutionContext()->GetTaskRunner(TaskType::kMiscPlatformAPI);
 }
 
 PermissionService* ClipboardPromise::GetPermissionService() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   if (!permission_service_) {
     ConnectToPermissionService(ExecutionContext::From(script_state_),
                                mojo::MakeRequest(&permission_service_));
@@ -130,12 +108,14 @@
 }
 
 bool ClipboardPromise::IsFocusedDocument(ExecutionContext* context) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   Document* doc = To<Document>(context);
   return doc && doc->hasFocus();
 }
 
 void ClipboardPromise::RequestReadPermission(
     PermissionService::RequestPermissionCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   DCHECK(script_promise_resolver_);
 
   ExecutionContext* context = ExecutionContext::From(script_state_);
@@ -157,6 +137,7 @@
 
 void ClipboardPromise::CheckWritePermission(
     PermissionService::HasPermissionCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   DCHECK(script_promise_resolver_);
 
   ExecutionContext* context = ExecutionContext::From(script_state_);
@@ -177,33 +158,46 @@
 }
 
 void ClipboardPromise::HandleRead() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   RequestReadPermission(WTF::Bind(&ClipboardPromise::HandleReadWithPermission,
                                   WrapPersistent(this)));
 }
 
-// TODO(garykac): This currently only handles plain text.
+// TODO(garykac): This currently only handles images and plain text.
 void ClipboardPromise::HandleReadWithPermission(PermissionStatus status) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   if (status != PermissionStatus::GRANTED) {
     script_promise_resolver_->Reject();
     return;
   }
 
-  String plain_text = SystemClipboard::GetInstance().ReadPlainText(buffer_);
+  String type_to_read = TypeToRead();
+  Blob* blob = nullptr;
 
-  const DataTransfer::DataTransferType type =
-      DataTransfer::DataTransferType::kCopyAndPaste;
-  const DataTransferAccessPolicy access = DataTransferAccessPolicy::kReadable;
-  DataObject* data = DataObject::CreateFromString(plain_text);
-  DataTransfer* dt = DataTransfer::Create(type, access, data);
-  script_promise_resolver_->Resolve(dt);
+  if (type_to_read == kMimeTypeImagePng) {
+    blob = ReadImageAsBlob();
+  } else if (type_to_read == kMimeTypeTextPlain) {
+    blob = ReadTextAsBlob();
+  } else {
+    // Reject when there's no data on clipboard.
+  }
+
+  if (!blob) {
+    script_promise_resolver_->Reject();
+    return;
+  }
+
+  script_promise_resolver_->Resolve(std::move(blob));
 }
 
 void ClipboardPromise::HandleReadText() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   RequestReadPermission(WTF::Bind(
       &ClipboardPromise::HandleReadTextWithPermission, WrapPersistent(this)));
 }
 
 void ClipboardPromise::HandleReadTextWithPermission(PermissionStatus status) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   if (status != PermissionStatus::GRANTED) {
     script_promise_resolver_->Reject();
     return;
@@ -213,116 +207,76 @@
   script_promise_resolver_->Resolve(text);
 }
 
-void ClipboardPromise::HandleReadImage() {
-  RequestReadPermission(WTF::Bind(
-      &ClipboardPromise::HandleReadImageWithPermission, WrapPersistent(this)));
-}
+// TODO(huangdarwin): This currently only handles plain text and images.
+// TODO(huangdarwin): Use an array or structure to hold multiple
+// Blobs, like how DataTransfer holds multiple DataTransferItems.
+void ClipboardPromise::HandleWrite(Blob* data) {
+  blob_data_ = data;
 
-void ClipboardPromise::HandleReadImageWithPermission(PermissionStatus status) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
-  if (status != PermissionStatus::GRANTED) {
-    script_promise_resolver_->Reject();
-    return;
-  }
-
-  SkBitmap bitmap = SystemClipboard::GetInstance().ReadImage(buffer_);
-
-  SkPixmap pixmap;
-  bitmap.peekPixels(&pixmap);
-
-  Vector<uint8_t> png_data;
-  SkPngEncoder::Options options;
-  if (!ImageEncoder::Encode(&png_data, pixmap, options)) {
-    script_promise_resolver_->Reject();
-    return;
-  }
-
-  std::unique_ptr<BlobData> data = BlobData::Create();
-  data->SetContentType(kMimeTypeImagePng);
-  data->AppendBytes(png_data.data(), png_data.size());
-  const uint64_t length = data->length();
-  scoped_refptr<BlobDataHandle> blob_data_handle =
-      BlobDataHandle::Create(std::move(data), length);
-
-  Blob* blob = Blob::Create(blob_data_handle);
-  script_promise_resolver_->Resolve(blob);
-}
-
-// TODO(garykac): This currently only handles plain text.
-void ClipboardPromise::HandleWrite(DataTransfer* data) {
-  // Scan DataTransfer and extract data types that we support.
-  uint32_t num_items = data->items()->length();
-  for (uint32_t i = 0; i < num_items; i++) {
-    DataTransferItem* item = data->items()->item(i);
-    DataObjectItem* objectItem = item->GetDataObjectItem();
-    if (objectItem->Kind() == DataObjectItem::kStringKind &&
-        objectItem->GetType() == kMimeTypeTextPlain) {
-      write_data_ = objectItem->GetAsString();
-      break;
-    }
-  }
   CheckWritePermission(WTF::Bind(&ClipboardPromise::HandleWriteWithPermission,
                                  WrapPersistent(this)));
 }
 
 void ClipboardPromise::HandleWriteWithPermission(PermissionStatus status) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   if (status != PermissionStatus::GRANTED) {
     script_promise_resolver_->Reject();
     return;
   }
 
-  SystemClipboard::GetInstance().WritePlainText(write_data_);
-  script_promise_resolver_->Resolve();
+  String type_to_read = blob_data_->type();
+  if (type_to_read == kMimeTypeImagePng || type_to_read == kMimeTypeTextPlain) {
+    DCHECK(!file_reader_);
+    file_reader_ = std::make_unique<ClipboardFileReader>(
+        blob_data_, this, file_reading_task_runner_);
+  } else {
+    script_promise_resolver_->Reject();
+  }
 }
 
 void ClipboardPromise::HandleWriteText(const String& data) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   write_data_ = data;
   CheckWritePermission(WTF::Bind(
       &ClipboardPromise::HandleWriteTextWithPermission, WrapPersistent(this)));
 }
 
-void ClipboardPromise::HandleWriteImage(Blob* data) {
-  write_image_data_ = data;
-
-  CheckWritePermission(WTF::Bind(
-      &ClipboardPromise::HandleWriteImageWithPermission, WrapPersistent(this)));
-}
-
-void ClipboardPromise::HandleWriteImageWithPermission(PermissionStatus status) {
-  if (status != PermissionStatus::GRANTED) {
-    script_promise_resolver_->Reject();
-    return;
-  }
-
-  file_reader_ = std::make_unique<ClipboardFileReader>(
-      write_image_data_, this, file_reading_task_runner_);
-}
-
 void ClipboardPromise::HandleWriteTextWithPermission(PermissionStatus status) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
   if (status != PermissionStatus::GRANTED) {
     script_promise_resolver_->Reject();
     return;
   }
 
-  SystemClipboard::GetInstance().WritePlainText(write_data_);
-  script_promise_resolver_->Resolve();
+  ResolveAndWriteText(write_data_);
 }
 
-void ClipboardPromise::OnLoadComplete(DOMArrayBuffer* array_buffer) {
+void ClipboardPromise::OnLoadBufferComplete(DOMArrayBuffer* array_buffer) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
+  String blob_type = blob_data_->type();
+  DCHECK(blob_type == kMimeTypeImagePng || blob_type == kMimeTypeTextPlain);
+
   file_reader_.reset();
 
-  // Schedule async image decode on another thread.
-  background_scheduler::PostOnBackgroundThread(
-      FROM_HERE,
-      CrossThreadBind(&ClipboardPromise::DecodeImageOnBackgroundThread,
-                      WrapCrossThreadPersistent(this), GetTaskRunner(),
-                      WrapCrossThreadPersistent(array_buffer)));
+  if (blob_type == kMimeTypeImagePng) {
+    background_scheduler::PostOnBackgroundThread(
+        FROM_HERE,
+        CrossThreadBind(&ClipboardPromise::DecodeImageOnBackgroundThread,
+                        WrapCrossThreadPersistent(this), GetTaskRunner(),
+                        WrapCrossThreadPersistent(array_buffer)));
+  } else if (blob_type == kMimeTypeTextPlain) {
+    background_scheduler::PostOnBackgroundThread(
+        FROM_HERE,
+        CrossThreadBind(&ClipboardPromise::DecodeTextOnBackgroundThread,
+                        WrapCrossThreadPersistent(this), GetTaskRunner(),
+                        WrapCrossThreadPersistent(array_buffer)));
+  }
 }
 
-// Reference: third_party/blink/renderer/core/imagebitmap/
-// TODO (crbug.com/916821): Ask ImageBitmapFactory owners if they can help
-// refactor and merge this very similar image decoding logic.
+// Reference: third_party/blink/renderer/core/imagebitmap/.
+// Logic modified from CropImageAndApplyColorSpaceConversion, but not using
+// directly due to extra complexity in imagebitmap that isn't necessary for
+// async clipboard image decoding.
 void ClipboardPromise::DecodeImageOnBackgroundThread(
     scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     DOMArrayBuffer* png_data) {
@@ -356,6 +310,20 @@
                       WrapCrossThreadPersistent(this), std::move(image)));
 }
 
+void ClipboardPromise::DecodeTextOnBackgroundThread(
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    DOMArrayBuffer* raw_data) {
+  DCHECK(!IsMainThread());
+
+  String wtf_string = String::FromUTF8(
+      reinterpret_cast<const LChar*>(raw_data->Data()), raw_data->ByteLength());
+
+  PostCrossThreadTask(
+      *task_runner, FROM_HERE,
+      CrossThreadBind(&ClipboardPromise::ResolveAndWriteText,
+                      WrapCrossThreadPersistent(this), std::move(wtf_string)));
+}
+
 void ClipboardPromise::ResolveAndWriteImage(sk_sp<SkImage> image) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
 
@@ -366,16 +334,68 @@
   script_promise_resolver_->Resolve();
 }
 
+void ClipboardPromise::ResolveAndWriteText(const String& text) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
+
+  SystemClipboard::GetInstance().WritePlainText(text);
+  script_promise_resolver_->Resolve();
+}
+
 void ClipboardPromise::Reject() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
 
   script_promise_resolver_->Reject();
 }
 
+// TODO(huangdarwin): This is beginning to share responsibility
+// with data_object.cc, so how can we share some code?
+String ClipboardPromise::TypeToRead() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
+  String type_to_read;
+  for (const String& available_type :
+       SystemClipboard::GetInstance().ReadAvailableTypes()) {
+    if (available_type == kMimeTypeImagePng)
+      return available_type;
+    if (available_type == kMimeTypeTextPlain)
+      type_to_read = available_type;
+  }
+  return type_to_read;
+}
+
+Blob* ClipboardPromise::ReadTextAsBlob() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
+
+  String plain_text = SystemClipboard::GetInstance().ReadPlainText(buffer_);
+
+  // Encode text to UTF-8, the standard text format for blobs.
+  CString utf_text = plain_text.Utf8();
+
+  return Blob::Create(reinterpret_cast<const unsigned char*>(utf_text.data()),
+                      utf_text.length(), kMimeTypeTextPlain);
+}
+
+Blob* ClipboardPromise::ReadImageAsBlob() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(async_clipboard_sequence_checker);
+
+  SkBitmap bitmap = SystemClipboard::GetInstance().ReadImage(buffer_);
+
+  // Encode bitmap to Vector<uint8_t> on main thread.
+  SkPixmap pixmap;
+  bitmap.peekPixels(&pixmap);
+
+  Vector<uint8_t> png_data;
+  SkPngEncoder::Options options;
+  if (!ImageEncoder::Encode(&png_data, pixmap, options)) {
+    return nullptr;
+  }
+
+  return Blob::Create(png_data.data(), png_data.size(), kMimeTypeImagePng);
+}
+
 void ClipboardPromise::Trace(blink::Visitor* visitor) {
   visitor->Trace(script_state_);
   visitor->Trace(script_promise_resolver_);
-  visitor->Trace(write_image_data_);
+  visitor->Trace(blob_data_);
   ContextLifecycleObserver::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
index eae508f..1b1d5390 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_promise.h
@@ -17,9 +17,10 @@
 
 namespace blink {
 
-class DataTransfer;
 class ScriptPromiseResolver;
 
+// TODO(huangdarwin): Split this class up. There are unrelated responsibilities
+// being handled in this class.
 class ClipboardPromise final
     : public GarbageCollectedFinalized<ClipboardPromise>,
       public ContextLifecycleObserver {
@@ -32,14 +33,10 @@
 
   static ScriptPromise CreateForRead(ScriptState*);
   static ScriptPromise CreateForReadText(ScriptState*);
-  // TODO (crbug.com/916823): Move ReadImage and WriteImage into Read/Write
-  // functions, so that the API surface doesn't change.
-  static ScriptPromise CreateForReadImage(ScriptState*);
-  static ScriptPromise CreateForWrite(ScriptState*, DataTransfer*);
+  static ScriptPromise CreateForWrite(ScriptState*, Blob*);
   static ScriptPromise CreateForWriteText(ScriptState*, const String&);
-  static ScriptPromise CreateForWriteImage(ScriptState*, Blob*);
 
-  void OnLoadComplete(DOMArrayBuffer*);
+  void OnLoadBufferComplete(DOMArrayBuffer*);
   void Reject();
 
   void Trace(blink::Visitor*) override;
@@ -48,11 +45,6 @@
   scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner();
   mojom::blink::PermissionService* GetPermissionService();
 
-  void DecodeImageOnBackgroundThread(
-      scoped_refptr<base::SingleThreadTaskRunner>,
-      DOMArrayBuffer*);
-  void ResolveAndWriteImage(sk_sp<SkImage>);
-
   bool IsFocusedDocument(ExecutionContext*);
 
   void RequestReadPermission(
@@ -66,26 +58,40 @@
   void HandleReadText();
   void HandleReadTextWithPermission(mojom::blink::PermissionStatus);
 
-  void HandleReadImage();
-  void HandleReadImageWithPermission(mojom::blink::PermissionStatus);
-
-  void HandleWrite(DataTransfer*);
+  void HandleWrite(Blob*);
   void HandleWriteWithPermission(mojom::blink::PermissionStatus);
 
   void HandleWriteText(const String&);
   void HandleWriteTextWithPermission(mojom::blink::PermissionStatus);
 
-  void HandleWriteImage(Blob*);
-  void HandleWriteImageWithPermission(mojom::blink::PermissionStatus);
+  void DecodeImageOnBackgroundThread(
+      scoped_refptr<base::SingleThreadTaskRunner>,
+      DOMArrayBuffer*);
+  void DecodeTextOnBackgroundThread(scoped_refptr<base::SingleThreadTaskRunner>,
+                                    DOMArrayBuffer*);
 
+  void ResolveAndWriteImage(sk_sp<SkImage>);
+  void ResolveAndWriteText(const String&);
+
+  // Detect whether an image or text is on the clipboard.
+  // Prioritizes image/png over text/plain over none.
+  String TypeToRead();
+
+  // Get Blob containing System Clipboard contents.
+  Blob* ReadTextAsBlob();
+  Blob* ReadImageAsBlob();
+
+  // Because v8 is thread-hostile, ensure that all interactions with ScriptState
+  // and ScriptPromiseResolver occur on the main thread.
   Member<ScriptState> script_state_;
   Member<ScriptPromiseResolver> script_promise_resolver_;
+
   std::unique_ptr<ClipboardFileReader> file_reader_;
   mojom::blink::PermissionServicePtr permission_service_;
   mojom::ClipboardBuffer buffer_;
 
   String write_data_;
-  Member<Blob> write_image_data_;
+  Member<Blob> blob_data_;
 
   scoped_refptr<base::SingleThreadTaskRunner> file_reading_task_runner_;
 
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
index dcb0c0a..fe64853 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl.cc
@@ -820,7 +820,9 @@
 
   // If we are in the "no-source" state we should show the overflow menu on a
   // video element.
-  if (IsModern()) {
+  // TODO(https://crbug.org/930001): Reconsider skipping this block when not
+  // connected.
+  if (IsModern() && MediaElement().isConnected()) {
     bool updated = false;
 
     if (state == kNoSource) {
@@ -848,6 +850,18 @@
       }
     }
 
+    if (state == kNoSource || state == kNotLoaded) {
+      if (!timeline_->hasAttribute(html_names::kDisabledAttr)) {
+        timeline_->setAttribute(html_names::kDisabledAttr, "");
+        updated = true;
+      }
+    } else {
+      if (timeline_->hasAttribute(html_names::kDisabledAttr)) {
+        timeline_->removeAttribute(html_names::kDisabledAttr);
+        updated = true;
+      }
+    }
+
     if (updated)
       UpdateOverflowMenuWanted();
   }
diff --git a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
index 24970dfd..470ffea 100644
--- a/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
+++ b/third_party/blink/renderer/modules/media_controls/media_controls_impl_test.cc
@@ -35,7 +35,9 @@
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_current_time_display_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_download_button_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_mute_button_element.h"
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_button_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_overflow_menu_list_element.h"
+#include "third_party/blink/renderer/modules/media_controls/elements/media_control_play_button_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_remaining_time_display_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_timeline_element.h"
 #include "third_party/blink/renderer/modules/media_controls/elements/media_control_volume_slider_element.h"
@@ -259,6 +261,13 @@
   MediaControlMuteButtonElement* MuteButtonElement() const {
     return media_controls_->mute_button_;
   }
+  MediaControlPlayButtonElement* PlayButtonElement() const {
+    return media_controls_->play_button_;
+  }
+  MediaControlOverflowMenuButtonElement* OverflowMenuButtonElement() const {
+    return media_controls_->overflow_menu_;
+  }
+
   MockWebMediaPlayerForImpl* WebMediaPlayer() {
     return static_cast<MockWebMediaPlayerForImpl*>(
         MediaControls().MediaElement().GetWebMediaPlayer());
@@ -1491,4 +1500,35 @@
   }
 }
 
+TEST_F(ModernMediaControlsImplTest, MediaControlsDisabledWithNoSource) {
+  EXPECT_EQ(MediaControls().State(), MediaControlsImpl::kNoSource);
+
+  EXPECT_TRUE(PlayButtonElement()->hasAttribute(html_names::kDisabledAttr));
+  EXPECT_TRUE(
+      OverflowMenuButtonElement()->hasAttribute(html_names::kDisabledAttr));
+  EXPECT_TRUE(TimelineElement()->hasAttribute(html_names::kDisabledAttr));
+
+  MediaControls().MediaElement().setAttribute(html_names::kPreloadAttr, "none");
+  MediaControls().MediaElement().SetSrc("https://example.com/foo.mp4");
+  test::RunPendingTasks();
+  SimulateLoadedMetadata();
+
+  EXPECT_EQ(MediaControls().State(), MediaControlsImpl::kNotLoaded);
+
+  EXPECT_FALSE(PlayButtonElement()->hasAttribute(html_names::kDisabledAttr));
+  EXPECT_FALSE(
+      OverflowMenuButtonElement()->hasAttribute(html_names::kDisabledAttr));
+  EXPECT_TRUE(TimelineElement()->hasAttribute(html_names::kDisabledAttr));
+
+  MediaControls().MediaElement().removeAttribute(html_names::kPreloadAttr);
+  SimulateLoadedMetadata();
+
+  EXPECT_EQ(MediaControls().State(), MediaControlsImpl::kLoadingMetadata);
+
+  EXPECT_FALSE(PlayButtonElement()->hasAttribute(html_names::kDisabledAttr));
+  EXPECT_FALSE(
+      OverflowMenuButtonElement()->hasAttribute(html_names::kDisabledAttr));
+  EXPECT_FALSE(TimelineElement()->hasAttribute(html_names::kDisabledAttr));
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/serial/serial.cc b/third_party/blink/renderer/modules/serial/serial.cc
index ff015fd..af09b85 100644
--- a/third_party/blink/renderer/modules/serial/serial.cc
+++ b/third_party/blink/renderer/modules/serial/serial.cc
@@ -10,7 +10,9 @@
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
+#include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
 #include "third_party/blink/renderer/modules/event_target_modules_names.h"
 #include "third_party/blink/renderer/modules/serial/serial_port.h"
@@ -19,6 +21,8 @@
 
 namespace {
 
+const char kFeaturePolicyBlocked[] =
+    "Access to the feature \"serial\" is disallowed by feature policy.";
 const char kNoPortSelected[] = "No port selected by the user.";
 
 String TokenToString(const base::UnguessableToken& token) {
@@ -47,12 +51,21 @@
 }
 
 ScriptPromise Serial::getPorts(ScriptState* script_state) {
-  if (!GetExecutionContext()) {
+  auto* context = GetExecutionContext();
+  if (!context) {
     return ScriptPromise::RejectWithDOMException(
         script_state,
         DOMException::Create(DOMExceptionCode::kNotSupportedError));
   }
 
+  if (!context->GetSecurityContext().IsFeatureEnabled(
+          mojom::FeaturePolicyFeature::kSerial,
+          ReportOptions::kReportOnFailure)) {
+    return ScriptPromise::RejectWithDOMException(
+        script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
+                                           kFeaturePolicyBlocked));
+  }
+
   auto* resolver = ScriptPromiseResolver::Create(script_state);
   get_ports_promises_.insert(resolver);
 
@@ -66,12 +79,20 @@
 ScriptPromise Serial::requestPort(ScriptState* script_state,
                                   const SerialPortRequestOptions* options) {
   auto* frame = GetFrame();
-  if (!frame) {
+  if (!frame || !frame->GetDocument()) {
     return ScriptPromise::RejectWithDOMException(
         script_state,
         DOMException::Create(DOMExceptionCode::kNotSupportedError));
   }
 
+  if (!frame->GetDocument()->IsFeatureEnabled(
+          mojom::FeaturePolicyFeature::kSerial,
+          ReportOptions::kReportOnFailure)) {
+    return ScriptPromise::RejectWithDOMException(
+        script_state, DOMException::Create(DOMExceptionCode::kSecurityError,
+                                           kFeaturePolicyBlocked));
+  }
+
   if (!LocalFrame::HasTransientUserActivation(frame)) {
     return ScriptPromise::RejectWithDOMException(
         script_state,
diff --git a/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc b/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc
index e7281bb..849b8455 100644
--- a/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc
+++ b/third_party/blink/renderer/modules/xr/xr_bounded_reference_space.cc
@@ -72,7 +72,7 @@
 
 void XRBoundedReferenceSpace::Trace(blink::Visitor* visitor) {
   visitor->Trace(bounds_geometry_);
-  XRSpace::Trace(visitor);
+  XRReferenceSpace::Trace(visitor);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_input_pose.cc b/third_party/blink/renderer/modules/xr/xr_input_pose.cc
index 44e626be..0bc41cd 100644
--- a/third_party/blink/renderer/modules/xr/xr_input_pose.cc
+++ b/third_party/blink/renderer/modules/xr/xr_input_pose.cc
@@ -12,19 +12,15 @@
                          std::unique_ptr<TransformationMatrix> grip_matrix,
                          bool emulated_position)
     : target_ray_(MakeGarbageCollected<XRRay>(std::move(pointer_matrix))),
-      grip_matrix_(std::move(grip_matrix)),
+      grip_transform_(
+          MakeGarbageCollected<XRRigidTransform>(std::move(grip_matrix))),
       emulated_position_(emulated_position) {}
 
 XRInputPose::~XRInputPose() {}
 
-DOMFloat32Array* XRInputPose::gripMatrix() const {
-  if (!grip_matrix_)
-    return nullptr;
-  return transformationMatrixToDOMFloat32Array(*grip_matrix_);
-}
-
 void XRInputPose::Trace(blink::Visitor* visitor) {
   visitor->Trace(target_ray_);
+  visitor->Trace(grip_transform_);
   ScriptWrappable::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/modules/xr/xr_input_pose.h b/third_party/blink/renderer/modules/xr/xr_input_pose.h
index 7d5448d..5b93669 100644
--- a/third_party/blink/renderer/modules/xr/xr_input_pose.h
+++ b/third_party/blink/renderer/modules/xr/xr_input_pose.h
@@ -5,8 +5,11 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_POSE_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_INPUT_POSE_H_
 
+#include <utility>
+
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
 #include "third_party/blink/renderer/modules/xr/xr_ray.h"
+#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
 #include "third_party/blink/renderer/platform/transforms/transformation_matrix.h"
@@ -24,14 +27,14 @@
   ~XRInputPose() override;
 
   XRRay* targetRay() const { return target_ray_; }
-  DOMFloat32Array* gripMatrix() const;
+  XRRigidTransform* gripTransform() const { return grip_transform_; }
   bool emulatedPosition() const { return emulated_position_; }
 
   void Trace(blink::Visitor*) override;
 
  private:
   const Member<XRRay> target_ray_;
-  const std::unique_ptr<TransformationMatrix> grip_matrix_;
+  Member<XRRigidTransform> grip_transform_;
   const bool emulated_position_;
 };
 
diff --git a/third_party/blink/renderer/modules/xr/xr_input_pose.idl b/third_party/blink/renderer/modules/xr/xr_input_pose.idl
index 0359c6a..bf7e012 100644
--- a/third_party/blink/renderer/modules/xr/xr_input_pose.idl
+++ b/third_party/blink/renderer/modules/xr/xr_input_pose.idl
@@ -7,7 +7,7 @@
     Exposed=Window,
     OriginTrialEnabled=WebXR
 ] interface XRInputPose {
-  readonly attribute XRRay targetRay;
-  readonly attribute Float32Array? gripMatrix;
   readonly attribute boolean emulatedPosition;
+  readonly attribute XRRay targetRay;
+  readonly attribute XRRigidTransform? gripTransform;
 };
diff --git a/third_party/blink/renderer/modules/xr/xr_reference_space.cc b/third_party/blink/renderer/modules/xr/xr_reference_space.cc
index 129ca76..12c9819 100644
--- a/third_party/blink/renderer/modules/xr/xr_reference_space.cc
+++ b/third_party/blink/renderer/modules/xr/xr_reference_space.cc
@@ -5,12 +5,17 @@
 #include "third_party/blink/renderer/modules/xr/xr_reference_space.h"
 
 #include "device/vr/public/mojom/vr_service.mojom-blink.h"
+#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
 #include "third_party/blink/renderer/modules/xr/xr_session.h"
 #include "third_party/blink/renderer/modules/xr/xr_stage_bounds.h"
 
 namespace blink {
 
-XRReferenceSpace::XRReferenceSpace(XRSession* session) : XRSpace(session) {}
+// origin offset starts as identity transform
+XRReferenceSpace::XRReferenceSpace(XRSession* session)
+    : XRSpace(session),
+      origin_offset_(MakeGarbageCollected<XRRigidTransform>(nullptr, nullptr)) {
+}
 
 XRReferenceSpace::~XRReferenceSpace() = default;
 
@@ -38,7 +43,12 @@
   return TransformBasePose(base_input_pose);
 }
 
+void XRReferenceSpace::setOriginOffset(XRRigidTransform* transform) {
+  origin_offset_ = transform;
+}
+
 void XRReferenceSpace::Trace(blink::Visitor* visitor) {
+  visitor->Trace(origin_offset_);
   XRSpace::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/modules/xr/xr_reference_space.h b/third_party/blink/renderer/modules/xr/xr_reference_space.h
index 3bc91e6..9614cea 100644
--- a/third_party/blink/renderer/modules/xr/xr_reference_space.h
+++ b/third_party/blink/renderer/modules/xr/xr_reference_space.h
@@ -10,11 +10,13 @@
 
 namespace blink {
 
+class XRRigidTransform;
+
 class XRReferenceSpace : public XRSpace {
   DEFINE_WRAPPERTYPEINFO();
 
  public:
-  XRReferenceSpace(XRSession*);
+  explicit XRReferenceSpace(XRSession*);
   ~XRReferenceSpace() override;
 
   virtual std::unique_ptr<TransformationMatrix> DefaultPose();
@@ -24,7 +26,13 @@
       const TransformationMatrix& base_input_pose,
       const TransformationMatrix& base_pose);
 
+  XRRigidTransform* originOffset() const { return origin_offset_; }
+  void setOriginOffset(XRRigidTransform*);
+
   void Trace(blink::Visitor*) override;
+
+ private:
+  Member<XRRigidTransform> origin_offset_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_reference_space.idl b/third_party/blink/renderer/modules/xr/xr_reference_space.idl
index a1dea45..da6d5c46 100644
--- a/third_party/blink/renderer/modules/xr/xr_reference_space.idl
+++ b/third_party/blink/renderer/modules/xr/xr_reference_space.idl
@@ -16,5 +16,6 @@
     Exposed=Window,
     OriginTrialEnabled=WebXR
 ] interface XRReferenceSpace : XRSpace {
+  attribute XRRigidTransform originOffset;
   attribute EventHandler onreset;
 };
diff --git a/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc b/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
index bd1f7f2..a4497bb 100644
--- a/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
+++ b/third_party/blink/renderer/modules/xr/xr_rigid_transform.cc
@@ -8,6 +8,61 @@
 
 namespace blink {
 
+// makes a deep copy of transformationMatrix
+XRRigidTransform::XRRigidTransform(
+    const TransformationMatrix& transformationMatrix)
+    : matrix_(TransformationMatrix::Create(transformationMatrix)) {
+  DecomposeMatrix();
+}
+
+// takes ownership of transformationMatrix instead of copying it
+XRRigidTransform::XRRigidTransform(
+    std::unique_ptr<TransformationMatrix> transformationMatrix)
+    : matrix_(std::move(transformationMatrix)) {
+  DecomposeMatrix();
+}
+
+void XRRigidTransform::DecomposeMatrix() {
+  // decompose matrix to position and orientation
+  TransformationMatrix::DecomposedType decomposed;
+  bool succeeded = matrix_->Decompose(decomposed);
+  if (succeeded) {
+    position_ =
+        DOMPointReadOnly::Create(decomposed.translate_x, decomposed.translate_y,
+                                 decomposed.translate_z, 1.0);
+    orientation_ = makeNormalizedQuaternion(
+        decomposed.quaternion_x, decomposed.quaternion_y,
+        decomposed.quaternion_z, decomposed.quaternion_w);
+  } else {
+    // TODO: Is this the correct way to handle a failure here?
+    position_ = DOMPointReadOnly::Create(0.0, 0.0, 0.0, 1.0);
+    orientation_ = DOMPointReadOnly::Create(0.0, 0.0, 0.0, 1.0);
+  }
+}
+
+// deep copy
+XRRigidTransform::XRRigidTransform(const XRRigidTransform& other) {
+  *this = other;
+}
+
+// deep copy
+XRRigidTransform& XRRigidTransform::operator=(const XRRigidTransform& other) {
+  if (&other == this)
+    return *this;
+
+  position_ =
+      DOMPointReadOnly::Create(other.position_->x(), other.position_->y(),
+                               other.position_->z(), other.position_->w());
+  orientation_ = DOMPointReadOnly::Create(
+      other.orientation_->x(), other.orientation_->y(), other.orientation_->z(),
+      other.orientation_->w());
+  if (other.matrix_) {
+    matrix_ = TransformationMatrix::Create(*(other.matrix_.get()));
+  }
+
+  return *this;
+}
+
 XRRigidTransform::XRRigidTransform(DOMPointInit* position,
                                    DOMPointInit* orientation) {
   if (position) {
@@ -18,7 +73,8 @@
   }
 
   if (orientation) {
-    orientation_ = makeNormalizedQuaternion(orientation);
+    orientation_ = makeNormalizedQuaternion(orientation->x(), orientation->y(),
+                                            orientation->z(), orientation->w());
   } else {
     orientation_ = DOMPointReadOnly::Create(0.0, 0.0, 0.0, 1.0);
   }
@@ -33,6 +89,17 @@
 }
 
 DOMFloat32Array* XRRigidTransform::matrix() {
+  EnsureMatrix();
+  return transformationMatrixToDOMFloat32Array(*matrix_);
+}
+
+TransformationMatrix XRRigidTransform::InverseMatrix() {
+  EnsureMatrix();
+  DCHECK(matrix_->IsInvertible());
+  return matrix_->Inverse();
+}
+
+void XRRigidTransform::EnsureMatrix() {
   if (!matrix_) {
     matrix_ = TransformationMatrix::Create();
     TransformationMatrix::DecomposedType decomp;
@@ -53,8 +120,6 @@
 
     matrix_->Recompose(decomp);
   }
-
-  return transformationMatrixToDOMFloat32Array(*matrix_);
 }
 
 void XRRigidTransform::Trace(blink::Visitor* visitor) {
diff --git a/third_party/blink/renderer/modules/xr/xr_rigid_transform.h b/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
index 247a3f74..4114acb 100644
--- a/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
+++ b/third_party/blink/renderer/modules/xr/xr_rigid_transform.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_RIGID_TRANSFORM_H_
 
 #include <memory>
+#include <utility>
 
 #include "third_party/blink/renderer/core/geometry/dom_point_init.h"
 #include "third_party/blink/renderer/core/geometry/dom_point_read_only.h"
@@ -19,6 +20,12 @@
   DEFINE_WRAPPERTYPEINFO();
 
  public:
+  // deep copies
+  XRRigidTransform(const XRRigidTransform& other);
+  XRRigidTransform& operator=(const XRRigidTransform& other);
+
+  explicit XRRigidTransform(const TransformationMatrix&);
+  explicit XRRigidTransform(std::unique_ptr<TransformationMatrix>);
   XRRigidTransform(DOMPointInit*, DOMPointInit*);
   static XRRigidTransform* Create(DOMPointInit*, DOMPointInit*);
 
@@ -26,9 +33,14 @@
   DOMPointReadOnly* orientation() const { return orientation_; }
   DOMFloat32Array* matrix();
 
+  TransformationMatrix InverseMatrix();
+
   void Trace(blink::Visitor*) override;
 
  private:
+  void DecomposeMatrix();
+  void EnsureMatrix();
+
   Member<DOMPointReadOnly> position_;
   Member<DOMPointReadOnly> orientation_;
   std::unique_ptr<TransformationMatrix> matrix_;
diff --git a/third_party/blink/renderer/modules/xr/xr_space.cc b/third_party/blink/renderer/modules/xr/xr_space.cc
index 066ab9e..fc27b87 100644
--- a/third_party/blink/renderer/modules/xr/xr_space.cc
+++ b/third_party/blink/renderer/modules/xr/xr_space.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/modules/xr/xr_space.h"
 
 #include "third_party/blink/renderer/modules/event_target_modules.h"
+#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
 #include "third_party/blink/renderer/modules/xr/xr_session.h"
 
 namespace blink {
@@ -15,7 +16,7 @@
 
 // If possible, get the matrix required to transform between two coordinate
 // systems.
-DOMFloat32Array* XRSpace::getTransformTo(XRSpace* other) const {
+XRRigidTransform* XRSpace::getTransformTo(XRSpace* other) const {
   if (session_ != other->session()) {
     // Cannot get relationships between coordinate systems that belong to
     // different sessions.
diff --git a/third_party/blink/renderer/modules/xr/xr_space.h b/third_party/blink/renderer/modules/xr/xr_space.h
index ca7460c9..9cc6804 100644
--- a/third_party/blink/renderer/modules/xr/xr_space.h
+++ b/third_party/blink/renderer/modules/xr/xr_space.h
@@ -13,6 +13,7 @@
 
 namespace blink {
 
+class XRRigidTransform;
 class XRSession;
 
 class XRSpace : public EventTargetWithInlineData {
@@ -22,7 +23,7 @@
   explicit XRSpace(XRSession*);
   ~XRSpace() override;
 
-  DOMFloat32Array* getTransformTo(XRSpace*) const;
+  XRRigidTransform* getTransformTo(XRSpace*) const;
 
   XRSession* session() const { return session_; }
 
diff --git a/third_party/blink/renderer/modules/xr/xr_space.idl b/third_party/blink/renderer/modules/xr/xr_space.idl
index 0115c41..6f74a4e 100644
--- a/third_party/blink/renderer/modules/xr/xr_space.idl
+++ b/third_party/blink/renderer/modules/xr/xr_space.idl
@@ -8,5 +8,5 @@
     Exposed=Window,
     OriginTrialEnabled=WebXR
 ] interface XRSpace : EventTarget {
-  Float32Array? getTransformTo(XRSpace other);
+  XRRigidTransform? getTransformTo(XRSpace other);
 };
diff --git a/third_party/blink/renderer/modules/xr/xr_utils.cc b/third_party/blink/renderer/modules/xr/xr_utils.cc
index 96ea9fa..0f8895ba 100644
--- a/third_party/blink/renderer/modules/xr/xr_utils.cc
+++ b/third_party/blink/renderer/modules/xr/xr_utils.cc
@@ -24,11 +24,10 @@
 }
 
 // Normalize to have length = 1.0
-DOMPointReadOnly* makeNormalizedQuaternion(DOMPointInit* q) {
-  double x = q->x();
-  double y = q->y();
-  double z = q->z();
-  double w = q->w();
+DOMPointReadOnly* makeNormalizedQuaternion(double x,
+                                           double y,
+                                           double z,
+                                           double w) {
   double length = std::sqrt((x * x) + (y * y) + (z * z) + (w * w));
   if (length == 0.0) {
     // Return a default value instead of crashing.
diff --git a/third_party/blink/renderer/modules/xr/xr_utils.h b/third_party/blink/renderer/modules/xr/xr_utils.h
index 70c3a6c3..40cdee65 100644
--- a/third_party/blink/renderer/modules/xr/xr_utils.h
+++ b/third_party/blink/renderer/modules/xr/xr_utils.h
@@ -15,7 +15,10 @@
 DOMFloat32Array* transformationMatrixToDOMFloat32Array(
     const TransformationMatrix&);
 
-DOMPointReadOnly* makeNormalizedQuaternion(DOMPointInit*);
+DOMPointReadOnly* makeNormalizedQuaternion(double x,
+                                           double y,
+                                           double z,
+                                           double w);
 
 }  // namespace blink
 
diff --git a/third_party/blink/renderer/modules/xr/xr_view.cc b/third_party/blink/renderer/modules/xr/xr_view.cc
index 9fab0a42..6787906 100644
--- a/third_party/blink/renderer/modules/xr/xr_view.cc
+++ b/third_party/blink/renderer/modules/xr/xr_view.cc
@@ -44,6 +44,9 @@
   AssignMatrices(other);
   offset_ = other.offset_;
 
+  transform_ =
+      MakeGarbageCollected<XRRigidTransform>(*(other.transform_.Get()));
+
   // Don't copy the inverse projection matrix because it is rarely used.
   // Just set this flag so that if UnprojectPointer is called, this matrix
   // gets computed.
@@ -221,12 +224,27 @@
   // matrix
   inv_pose_matrix.PostTranslate3d(-offset_.X(), -offset_.Y(), -offset_.Z());
   view_matrix_ = transformationMatrixToDOMFloat32Array(inv_pose_matrix);
+
+  // transform's matrix is the inverse of the view matrix
+  // can't use the original pose matrix because it has translation applied
+  // after taking the inverse
+  // compute the inverse lazily
+  DCHECK(inv_pose_matrix.IsInvertible());
+  inv_pose_ = TransformationMatrix::Create(inv_pose_matrix);
+}
+
+XRRigidTransform* XRView::transform() {
+  if (!transform_) {
+    transform_ = MakeGarbageCollected<XRRigidTransform>(inv_pose_->Inverse());
+  }
+  return transform_;
 }
 
 void XRView::Trace(blink::Visitor* visitor) {
   visitor->Trace(session_);
   visitor->Trace(projection_matrix_);
   visitor->Trace(view_matrix_);
+  visitor->Trace(transform_);
   ScriptWrappable::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/modules/xr/xr_view.h b/third_party/blink/renderer/modules/xr/xr_view.h
index fe6f515..cd79fea 100644
--- a/third_party/blink/renderer/modules/xr/xr_view.h
+++ b/third_party/blink/renderer/modules/xr/xr_view.h
@@ -13,6 +13,8 @@
 #include "third_party/blink/renderer/platform/wtf/forward.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
 
+#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
+
 namespace blink {
 
 class XRSession;
@@ -24,9 +26,6 @@
   enum XREye { kEyeLeft = 0, kEyeRight = 1 };
 
   XRView(XRSession*, XREye);
-
-  // Default constructor, which I think is needed along with the copy
-  // constructors to make a deep copy of HeapVector<Member<XRView>>
   XRView();
 
   // Make deep copies.
@@ -39,6 +38,7 @@
   XRSession* session() const;
   DOMFloat32Array* projectionMatrix() const { return projection_matrix_; }
   DOMFloat32Array* viewMatrix() const { return view_matrix_; }
+  XRRigidTransform* transform();
 
   void UpdateProjectionMatrixFromRawValues(
       const WTF::Vector<float>& projection_matrix,
@@ -76,9 +76,11 @@
   XREye eye_;
   String eye_string_;
   Member<XRSession> session_;
+  Member<XRRigidTransform> transform_;
   Member<DOMFloat32Array> projection_matrix_;
   Member<DOMFloat32Array> view_matrix_;
   FloatPoint3D offset_;
+  std::unique_ptr<TransformationMatrix> inv_pose_;
   std::unique_ptr<TransformationMatrix> inv_projection_;
   bool inv_projection_dirty_ = true;
 };
diff --git a/third_party/blink/renderer/modules/xr/xr_view.idl b/third_party/blink/renderer/modules/xr/xr_view.idl
index c632509..ada2c33 100644
--- a/third_party/blink/renderer/modules/xr/xr_view.idl
+++ b/third_party/blink/renderer/modules/xr/xr_view.idl
@@ -16,4 +16,5 @@
   readonly attribute XREye eye;
   readonly attribute Float32Array projectionMatrix;
   readonly attribute Float32Array viewMatrix;
+  readonly attribute XRRigidTransform transform;
 };
diff --git a/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc b/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
index 90693f3e..8543bd85 100644
--- a/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
+++ b/third_party/blink/renderer/modules/xr/xr_viewer_pose.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/renderer/modules/xr/xr_viewer_pose.h"
 
+#include "third_party/blink/renderer/modules/xr/xr_rigid_transform.h"
 #include "third_party/blink/renderer/modules/xr/xr_session.h"
 #include "third_party/blink/renderer/modules/xr/xr_utils.h"
 #include "third_party/blink/renderer/modules/xr/xr_view.h"
@@ -13,11 +14,11 @@
 XRViewerPose::XRViewerPose(
     XRSession* session,
     std::unique_ptr<TransformationMatrix> pose_model_matrix)
-    : session_(session), pose_model_matrix_(std::move(pose_model_matrix)) {
+    : session_(session),
+      transform_(MakeGarbageCollected<XRRigidTransform>(
+          std::move(pose_model_matrix))) {
   // Can only update views with an invertible matrix.
-  DCHECK(pose_model_matrix_->IsInvertible());
-
-  TransformationMatrix inv_pose_matrix = pose_model_matrix_->Inverse();
+  TransformationMatrix inv_pose_matrix = transform_->InverseMatrix();
 
   // session will update views if required
   // views array gets copied to views_
@@ -28,18 +29,9 @@
   }
 }
 
-const HeapVector<Member<XRView>>& XRViewerPose::views() const {
-  return views_;
-}
-
-DOMFloat32Array* XRViewerPose::poseModelMatrix() const {
-  if (!pose_model_matrix_)
-    return nullptr;
-  return transformationMatrixToDOMFloat32Array(*pose_model_matrix_);
-}
-
 void XRViewerPose::Trace(blink::Visitor* visitor) {
   visitor->Trace(session_);
+  visitor->Trace(transform_);
   visitor->Trace(views_);
   ScriptWrappable::Trace(visitor);
 }
diff --git a/third_party/blink/renderer/modules/xr/xr_viewer_pose.h b/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
index e565e2c..321bfc2 100644
--- a/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
+++ b/third_party/blink/renderer/modules/xr/xr_viewer_pose.h
@@ -5,6 +5,8 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_VIEWER_POSE_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_XR_XR_VIEWER_POSE_H_
 
+#include <utility>
+
 #include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -12,6 +14,7 @@
 
 namespace blink {
 
+class XRRigidTransform;
 class XRSession;
 class XRView;
 
@@ -21,14 +24,14 @@
  public:
   XRViewerPose(XRSession*, std::unique_ptr<TransformationMatrix>);
 
-  DOMFloat32Array* poseModelMatrix() const;
-  const HeapVector<Member<XRView>>& views() const;
+  XRRigidTransform* transform() const { return transform_; }
+  const HeapVector<Member<XRView>>& views() const { return views_; }
 
   void Trace(blink::Visitor*) override;
 
  private:
   const Member<XRSession> session_;
-  std::unique_ptr<TransformationMatrix> pose_model_matrix_;
+  Member<XRRigidTransform> transform_;
   HeapVector<Member<XRView>> views_;
 };
 
diff --git a/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl b/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
index 7b1de70..9ebc6443 100644
--- a/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
+++ b/third_party/blink/renderer/modules/xr/xr_viewer_pose.idl
@@ -9,6 +9,6 @@
     Exposed=Window,
     OriginTrialEnabled=WebXR
 ] interface XRViewerPose {
-  readonly attribute Float32Array poseModelMatrix;
+  readonly attribute XRRigidTransform transform;
   readonly attribute FrozenArray<XRView> views;
 };
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 0edcdade..ac4d82e 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -96,10 +96,6 @@
       status: "experimental",
     },
     {
-      name: "AsyncClipboardImages",
-      status: "experimental",
-    },
-    {
       name: "AudioOutputDevices",
       status: "stable",
     },
@@ -887,10 +883,6 @@
       status: "stable",
     },
     {
-      name: "NullableDocumentDomain",
-      status: "experimental",
-    },
-    {
       name: "OffMainThreadCSSPaint",
     },
     {
diff --git a/third_party/blink/renderer/platform/weborigin/security_origin.cc b/third_party/blink/renderer/platform/weborigin/security_origin.cc
index 66b11ea0..49a2441 100644
--- a/third_party/blink/renderer/platform/weborigin/security_origin.cc
+++ b/third_party/blink/renderer/platform/weborigin/security_origin.cc
@@ -335,10 +335,7 @@
       if (host_ == other->host_ && port_ == other->port_)
         can_access = true;
     } else if (domain_was_set_in_dom_ && other->domain_was_set_in_dom_) {
-      // TODO(mkwst): If/when we ship this behavior, change this to check
-      // IsNull() rather than relying on string comparison.
-      // https://crbug.com/733150
-      if (domain_ == other->domain_ && domain_ != "null") {
+      if (domain_ == other->domain_) {
         can_access = true;
         detail = (host_ == other->host_ && port_ == other->port_)
                      ? AccessResultDomainDetail::kDomainMatchUnnecessary
diff --git a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
index 478193a..e30fe3e 100644
--- a/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
+++ b/third_party/blink/web_tests/FlagExpectations/enable-blink-features=LayoutNG
@@ -321,6 +321,8 @@
 crbug.com/591099 paint/invalidation/flexbox/scrollbars-changed.html [ Failure ]
 crbug.com/835484 paint/invalidation/outline/inline-focus.html [ Failure ]
 crbug.com/591099 paint/invalidation/overflow/opacity-change-on-overflow-float.html [ Failure ]
+crbug.com/930034 paint/invalidation/selection/japanese-rl-selection-clear.html [ Failure ]
+crbug.com/930034 paint/invalidation/selection/selection-rl.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/svg-background-partial-redraw.html [ Failure ]
 crbug.com/591099 paint/invalidation/svg/text-selection-update.svg [ Failure ]
 crbug.com/591099 paint/invalidation/svg/transform-focus-ring-repaint.html [ Failure ]
diff --git a/third_party/blink/web_tests/NeverFixTests b/third_party/blink/web_tests/NeverFixTests
index a155b6f0..15975b60 100644
--- a/third_party/blink/web_tests/NeverFixTests
+++ b/third_party/blink/web_tests/NeverFixTests
@@ -1732,10 +1732,10 @@
 external/wpt/battery-status/battery-charging-manual.https.html [ WontFix ]
 external/wpt/battery-status/battery-plugging-in-manual.https.html [ WontFix ]
 external/wpt/battery-status/battery-unplugging-manual.https.html [ WontFix ]
-external/wpt/clipboard-apis/async-write-dttext-read-dttext-manual.https.html [ WontFix ]
-external/wpt/clipboard-apis/async-write-dttext-read-text-manual.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-write-blobtext-read-text-manual.https.html [ WontFix ]
 external/wpt/clipboard-apis/async-write-image-read-image-manual.https.html [ WontFix ]
-external/wpt/clipboard-apis/async-write-text-read-dttext-manual.https.html [ WontFix ]
+external/wpt/clipboard-apis/async-write-text-read-blobtext-manual.https.html [ WontFix ]
 external/wpt/clipboard-apis/async-write-text-read-text-manual.https.html [ WontFix ]
 external/wpt/clipboard-apis/copy-event-manual.html [ WontFix ]
 external/wpt/clipboard-apis/cut-event-manual.html [ WontFix ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index aca5e51..b8ff288 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1792,6 +1792,7 @@
 crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-single-space-inline-element.html [ Timeout Failure ]
 crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-single-space-one-element.html [ Timeout Failure ]
 crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-by-word-visually-wrong-left-right.html [ Crash Failure ]
+crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_crossing_inline_block_boundary.html [ Failure ]
 crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move-forward-after-line-break.html [ Failure ]
 crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_br.html [ Failure ]
 crbug.com/894651 virtual/bidi-caret-affinity/editing/selection/modify_move/move_forward_line_range.html [ Failure ]
@@ -6046,3 +6047,6 @@
 crbug.com/929122 [ Linux ] external/wpt/html/dom/interfaces.worker.html [ Timeout Failure ]
 crbug.com/929355 [ Linux ] external/wpt/webrtc/RTCPeerConnection-track-stats.https.html [ Pass Failure ]
 crbug.com/929435 [ Mac ] external/wpt/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html [ Pass Failure ]
+
+# Sheriff 2019-02-07
+crbug.com/929929 external/wpt/background-fetch/fetch.https.window.html [ Pass Timeout ]
diff --git a/third_party/blink/web_tests/bindings/idl-dictionary-unittest-expected.txt b/third_party/blink/web_tests/bindings/idl-dictionary-unittest-expected.txt
index 74d98c0..6119b6c 100644
--- a/third_party/blink/web_tests/bindings/idl-dictionary-unittest-expected.txt
+++ b/third_party/blink/web_tests/bindings/idl-dictionary-unittest-expected.txt
@@ -1,4 +1,4 @@
-CONSOLE WARNING: line 273: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
+CONSOLE WARNING: line 277: 'window.webkitStorageInfo' is deprecated. Please use 'navigator.webkitTemporaryStorage' or 'navigator.webkitPersistentStorage' instead.
 IDL dictionary unittest
 
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
@@ -148,6 +148,10 @@
 PASS dictionaryTest.set({elementMember: document}) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': member elementMember is not of type Element..
 
 
+Test for setting invalid callback function value
+PASS dictionaryTest.set({callbackFunctionMember: {}}) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': member callbackFunctionMember is not a function..
+
+
 Test for passing invalid dictionary values
 PASS dictionaryTest.set(42) threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': parameter 1 ('testingDictionary') is not an object..
 PASS dictionaryTest.set('string') threw exception TypeError: Failed to execute 'set' on 'DictionaryTest': parameter 1 ('testingDictionary') is not an object..
diff --git a/third_party/blink/web_tests/bindings/idl-dictionary-unittest.html b/third_party/blink/web_tests/bindings/idl-dictionary-unittest.html
index 971ef39..75afc3fbd 100644
--- a/third_party/blink/web_tests/bindings/idl-dictionary-unittest.html
+++ b/third_party/blink/web_tests/bindings/idl-dictionary-unittest.html
@@ -253,6 +253,10 @@
     shouldThrow("dictionaryTest.set({elementMember: document})");
     debug('');
 
+    debug('Test for setting invalid callback function value');
+    shouldThrow("dictionaryTest.set({callbackFunctionMember: {}})");
+    debug('');
+
     debug('Test for passing invalid dictionary values');
     shouldThrow("dictionaryTest.set(42)");
     shouldThrow("dictionaryTest.set('string')");
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html
index e37669de0..24e5ab9 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-navigator-clipboard-basics.https.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
-<title>Async Clipboard basic tests</title>
+<title>Async Clipboard input type validation tests</title>
 <script src="../../resources/testharness.js"></script>
 <script src="../../resources/testharnessreport.js"></script>
 <script src="../../http/tests/resources/permissions-helper.js"></script>
@@ -18,32 +18,31 @@
   assert_equals(navigator.clipboard, navigator.clipboard);
 }, "navigator.clipboard exists");
 
-/* clipboard.write() */
+/* clipboard.write(Blob/text) */
 
 promise_test(async () => {
   await getPermissions();
-  const dt = new DataTransfer();
-  dt.items.add("Howdy", "text/plain");
-  await navigator.clipboard.write(dt);
-}, "navigator.clipboard.write(DataTransfer) succeeds");
+  const blob = new Blob(["hello"], {type: 'text/plain'});
+  await navigator.clipboard.write(blob);
+}, "navigator.clipboard.write(Blob) succeeds");
 
 promise_test(async t => {
   await getPermissions();
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write());
-}, "navigator.clipboard.write() fails (expect DataTransfer)");
+}, "navigator.clipboard.write() fails (expect Blob)");
 
 promise_test(async t => {
   await getPermissions();
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write(null));
-}, "navigator.clipboard.write(null) fails (expect DataTransfer)");
+}, "navigator.clipboard.write(null) fails (expect Blob)");
 
 promise_test(async t => {
   await getPermissions();
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write("Bad string"));
-}, "navigator.clipboard.write(DOMString) fails (expect DataTransfer)");
+}, "navigator.clipboard.write(DOMString) fails (expect Blob)");
 
 
 /* clipboard.writeText() */
@@ -59,13 +58,13 @@
                          navigator.clipboard.writeText());
 }, "navigator.clipboard.writeText() fails (expect DOMString)");
 
-
-/* clipboard.read() */
+/* Blob/text or Blob/imageclipboard.read() */
 
 promise_test(async () => {
   await getPermissions();
   const result = await navigator.clipboard.read();
-  assert_true(result instanceof DataTransfer);
+  assert_true(result instanceof Blob);
+  assert_equals(typeof result, "object");
 }, "navigator.clipboard.read() succeeds");
 
 
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-blobtext-read-blobtext.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-blobtext-read-blobtext.https.html
new file mode 100644
index 0000000..7a516c3
--- /dev/null
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-blobtext-read-blobtext.https.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Async Clipboard write (Blob/text) -> read (Blob/text) tests</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/permissions-helper.js"></script>
+<script>
+async function readWriteTest(textInput) {
+  promise_test(async t => {
+    await PermissionsHelper.setPermission('clipboard-read', 'granted');
+    await PermissionsHelper.setPermission('clipboard-write', 'granted');
+
+    const blobInput = new Blob([textInput], {type: 'text/plain'});
+
+    await navigator.clipboard.write(blobInput);
+    const blobOutput = await navigator.clipboard.read();
+    assert_equals(blobOutput.type, "text/plain");
+
+    const textOutput = await (new Response(blobOutput)).text();
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
+
+readWriteTest("Clipboard write (Blob/text) -> read (Blob/text) test");
+readWriteTest("non-Latin1 text encoding test データ");
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-blobtext-read-text.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-blobtext-read-text.https.html
new file mode 100644
index 0000000..d77c31c
--- /dev/null
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-blobtext-read-text.https.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Async Clipboard write (Blob/text) -> readText tests</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/permissions-helper.js"></script>
+<script>
+async function readWriteTest(textInput) {
+  promise_test(async t => {
+    await PermissionsHelper.setPermission('clipboard-read', 'granted');
+    await PermissionsHelper.setPermission('clipboard-write', 'granted');
+
+    const blobInput = new Blob([textInput], {type: 'text/plain'});
+
+    await navigator.clipboard.write(blobInput);
+    const textOutput = await navigator.clipboard.readText();
+
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
+
+readWriteTest("Clipboard write (Blob/text) -> read text test");
+readWriteTest("non-Latin1 text encoding test データ");
+</script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-dttext-read-dttext.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-dttext-read-dttext.https.html
deleted file mode 100644
index 22838cd..0000000
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-dttext-read-dttext.https.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Async Clipboard write (dt/text) -> read (dt/text) tests</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../http/tests/resources/permissions-helper.js"></script>
-<script>
-promise_test(async t => {
-  await PermissionsHelper.setPermission('clipboard-read', 'granted');
-  await PermissionsHelper.setPermission('clipboard-write', 'granted');
-
-  const input = "Clipboard write (dt/text) -> read (dt/text) test data";
-  const dt = new DataTransfer();
-  dt.items.add(input, "text/plain");
-
-  await navigator.clipboard.write(dt);
-  const output = await navigator.clipboard.read();
-
-  assert_equals(output.items.length, 1);
-  const result_promise = new Promise(resolve => {
-    output.items[0].getAsString(resolve);
-  });
-  const string_output = await result_promise;
-  assert_equals(string_output, input);
-}, "Verify write and read clipboard (DataTransfer/text)");
-</script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-dttext-read-text.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-dttext-read-text.https.html
deleted file mode 100644
index 22bd804..0000000
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-dttext-read-text.https.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Async Clipboard writeText -> read (dt/text) tests</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../http/tests/resources/permissions-helper.js"></script>
-<script>
-promise_test(async t => {
-  await PermissionsHelper.setPermission('clipboard-read', 'granted');
-  await PermissionsHelper.setPermission('clipboard-write', 'granted');
-
-  const input = "Clipboard writeText -> read (dt/text) test data";
-
-  await navigator.clipboard.writeText(input);
-  const output = await navigator.clipboard.read();
-
-  assert_equals(output.items.length, 1);
-  const result_promise = new Promise(resolve => {
-    output.items[0].getAsString(resolve);
-  });
-  const string_output = await result_promise;
-  assert_equals(string_output, input);
-}, "Verify write and read clipboard (DOMString)");
-</script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-blobtext.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-blobtext.https.html
new file mode 100644
index 0000000..8809e49
--- /dev/null
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-blobtext.https.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Async Clipboard writeText -> read (Blob/text) tests</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="../../http/tests/resources/permissions-helper.js"></script>
+<script>
+async function readWriteTest(textInput) {
+  promise_test(async t => {
+    await PermissionsHelper.setPermission('clipboard-read', 'granted');
+    await PermissionsHelper.setPermission('clipboard-write', 'granted');
+
+    await navigator.clipboard.writeText(textInput);
+    const blobOutput = await navigator.clipboard.read();
+    assert_equals(blobOutput.type, "text/plain");
+
+    const textOutput = await (new Response(blobOutput)).text();
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
+
+readWriteTest("Clipboard write text -> read (Blob/text) test");
+readWriteTest("non-Latin1 text encoding test データ");
+</script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-dttext.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-dttext.https.html
deleted file mode 100644
index 22bd804..0000000
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-dttext.https.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Async Clipboard writeText -> read (dt/text) tests</title>
-<script src="../../resources/testharness.js"></script>
-<script src="../../resources/testharnessreport.js"></script>
-<script src="../../http/tests/resources/permissions-helper.js"></script>
-<script>
-promise_test(async t => {
-  await PermissionsHelper.setPermission('clipboard-read', 'granted');
-  await PermissionsHelper.setPermission('clipboard-write', 'granted');
-
-  const input = "Clipboard writeText -> read (dt/text) test data";
-
-  await navigator.clipboard.writeText(input);
-  const output = await navigator.clipboard.read();
-
-  assert_equals(output.items.length, 1);
-  const result_promise = new Promise(resolve => {
-    output.items[0].getAsString(resolve);
-  });
-  const string_output = await result_promise;
-  assert_equals(string_output, input);
-}, "Verify write and read clipboard (DOMString)");
-</script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-text.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-text.https.html
index b649316..8c2e09a 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-text.https.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/async-write-text-read-text.https.html
@@ -5,15 +5,18 @@
 <script src="../../resources/testharnessreport.js"></script>
 <script src="../../http/tests/resources/permissions-helper.js"></script>
 <script>
-promise_test(async t => {
+async function readWriteTest(textInput) {
   await PermissionsHelper.setPermission('clipboard-read', 'granted');
   await PermissionsHelper.setPermission('clipboard-write', 'granted');
 
-  const input = "Clipboard writeText -> readText test data";
+  promise_test(async t => {
+    await navigator.clipboard.writeText(textInput);
+    const textOutput = await navigator.clipboard.readText();
 
-  await navigator.clipboard.writeText(input);
-  const output = await navigator.clipboard.readText();
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
 
-  assert_equals(output, input);
-}, "Verify write and read clipboard (DOMString)");
+readWriteTest("Clipboard write text -> read text test");
+readWriteTest("non-Latin1 text encoding test データ");
 </script>
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/readtext-denied.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/readtext-denied.https.html
index 91953ab..b24d3f7 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/readtext-denied.https.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/readtext-denied.https.html
@@ -9,14 +9,14 @@
   await PermissionsHelper.setPermission('clipboard-read', 'denied');
   // Note: Failure returns a rejected promise of type undefined, so
   // promise_rejects doesn't seem to work here.
-  let promise_rejected = false;
+  let promiseRejected = false;
   try {
     await navigator.clipboard.readText();
   }
   catch {
-    promise_rejected = true;
+    promiseRejected = true;
   }
-  if(promise_rejected === false) {
+  if(promiseRejected === false) {
     throw "readText should have failed with permission denied, but succeeded "
           + "instead";
   }
diff --git a/third_party/blink/web_tests/clipboard/async-clipboard/writetext-denied.https.html b/third_party/blink/web_tests/clipboard/async-clipboard/writetext-denied.https.html
index 3736338..1a71c28 100644
--- a/third_party/blink/web_tests/clipboard/async-clipboard/writetext-denied.https.html
+++ b/third_party/blink/web_tests/clipboard/async-clipboard/writetext-denied.https.html
@@ -9,14 +9,14 @@
   await PermissionsHelper.setPermission('clipboard-write', 'denied');
   // Note: Failure returns a rejected promise of type undefined, so
   // promise_rejects doesn't seem to work here.
-  let promise_rejected = false;
+  let promiseRejected = false;
   try {
     await navigator.clipboard.writeText("xyz");
   }
   catch {
-    promise_rejected = true;
+    promiseRejected = true;
   }
-  if(promise_rejected === false) {
+  if(promiseRejected === false) {
     throw "writeText should have failed with permission denied, but succeeded "
           + "instead";
   }
diff --git a/third_party/blink/web_tests/editing/selection/modify_move/move_crossing_inline_block_boundary.html b/third_party/blink/web_tests/editing/selection/modify_move/move_crossing_inline_block_boundary.html
new file mode 100644
index 0000000..17556164
--- /dev/null
+++ b/third_party/blink/web_tests/editing/selection/modify_move/move_crossing_inline_block_boundary.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+<script src="../../assert_selection.js"></script>
+<script>
+selection_test(
+    '<div contenteditable>foo|<span style="display:inline-block">bar</span>baz</div>',
+    selection => selection.modify('move', 'right', 'character'),
+    '<div contenteditable>foo<span style="display:inline-block">b|ar</span>baz</div>',
+    'Move right into inline block');
+
+selection_test(
+    '<div contenteditable>foo<span style="display:inline-block">|bar</span>baz</div>',
+    selection => selection.modify('move', 'left', 'character'),
+    '<div contenteditable>fo|o<span style="display:inline-block">bar</span>baz</div>',
+    'Move left out of inline block');
+
+selection_test(
+    '<div contenteditable>foo<span style="display:inline-block">bar</span>|baz</div>',
+    selection => selection.modify('move', 'left', 'character'),
+    '<div contenteditable>foo<span style="display:inline-block">ba|r</span>baz</div>',
+    'Move left into inline block');
+
+selection_test(
+    '<div contenteditable>foo<span style="display:inline-block">bar|</span>baz</div>',
+    selection => selection.modify('move', 'right', 'character'),
+    '<div contenteditable>foo<span style="display:inline-block">bar</span>b|az</div>',
+    'Move right out of inline block');
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-basics.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-basics.https.html
index ea0ca29..5a23598 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-basics.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-navigator-clipboard-basics.https.html
@@ -11,28 +11,27 @@
   assert_equals(navigator.clipboard, navigator.clipboard);
 }, "navigator.clipboard exists");
 
-/* clipboard.write() */
+/* clipboard.write(Blob/text) */
 
 promise_test(async () => {
-  const dt = new DataTransfer();
-  dt.items.add("Howdy", "text/plain");
-  await navigator.clipboard.write(dt);
-}, "navigator.clipboard.write(DataTransfer) succeeds");
+  const blob = new Blob(["hello"], {type: 'text/plain'});
+  await navigator.clipboard.write(blob);
+}, "navigator.clipboard.write(Blob) succeeds");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write());
-}, "navigator.clipboard.write() fails (expect DataTransfer)");
+}, "navigator.clipboard.write() fails (expect Blob)");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write(null));
-}, "navigator.clipboard.write(null) fails (expect DataTransfer)");
+}, "navigator.clipboard.write(null) fails (expect Blob)");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
                          navigator.clipboard.write("Bad string"));
-}, "navigator.clipboard.write(DOMString) fails (expect DataTransfer)");
+}, "navigator.clipboard.write(DOMString) fails (expect Blob)");
 
 
 /* clipboard.writeText() */
@@ -46,27 +45,28 @@
                          navigator.clipboard.writeText());
 }, "navigator.clipboard.writeText() fails (expect DOMString)");
 
-/* clipboard.writeImageExperimental() */
+/* clipboard.write(Blob/image) */
 
 promise_test(async () => {
   const fetched = await fetch(
         'http://localhost:8001/clipboard-apis/resources/greenbox.png');
   const image = await fetched.blob();
 
-  await navigator.clipboard.writeImageExperimental(image);
+  await navigator.clipboard.write(image);
 }, "navigator.clipboard.writeImageExperimental(Blob) succeeds");
 
 promise_test(async t => {
   await promise_rejects(t, new TypeError(),
-                        navigator.clipboard.writeImageExperimental());
+                        navigator.clipboard.write());
 }, "navigator.clipboard.writeImageExperimental() fails (expect Blob)");
 
 
-/* clipboard.read() */
+/* Blob/text or Blob/image clipboard.read() */
 
 promise_test(async () => {
   const result = await navigator.clipboard.read();
-  assert_true(result instanceof DataTransfer);
+  assert_true(result instanceof Blob);
+  assert_equals(typeof result, "object");
 }, "navigator.clipboard.read() succeeds");
 
 
@@ -77,11 +77,4 @@
   assert_equals(typeof result, "string");
 }, "navigator.clipboard.readText() succeeds");
 
-/* clipboard.readImageExperimental() */
-
-promise_test(async () => {
-  const result = await navigator.clipboard.readImageExperimental();
-  assert_equals(typeof result, "object");
-}, "navigator.clipboard.readImageExperimental() succeeds");
-
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html
new file mode 100644
index 0000000..f860bf23
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobtext-read-blobtext-manual.https.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Async Clipboard write (Blob/text) -> read (Blob/text) tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async function readWriteTest(textInput) {
+  promise_test(async t => {
+    const blobInput = new Blob([textInput], {type: 'text/plain'});
+
+    await navigator.clipboard.write(blobInput);
+    const blobOutput = await navigator.clipboard.read();
+    assert_equals(blobOutput.type, "text/plain");
+
+    const textOutput = await (new Response(blobOutput)).text();
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
+
+readWriteTest("Clipboard write (Blob/text) -> read (Blob/text) test");
+readWriteTest("non-Latin1 text encoding test データ");
+</script>
+<p>
+  Note: This is a manual test because it writes/reads to the shared system
+  clipboard and thus cannot be run async with other tests that might interact
+  with the clipboard.
+</p>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobtext-read-text-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobtext-read-text-manual.https.html
new file mode 100644
index 0000000..685b6cb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-blobtext-read-text-manual.https.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Async Clipboard write (Blob/text) -> readText tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async function readWriteTest(textInput) {
+  promise_test(async t => {
+    const blobInput = new Blob([textInput], {type: 'text/plain'});
+
+    await navigator.clipboard.write(blobInput);
+    const textOutput = await navigator.clipboard.readText();
+
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
+
+readWriteTest("Clipboard write (Blob/text) -> read text test");
+readWriteTest("non-Latin1 text encoding test データ");
+</script>
+<p>
+  Note: This is a manual test because it writes/reads to the shared system
+  clipboard and thus cannot be run async with other tests that might interact
+  with the clipboard.
+</p>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-dttext-read-dttext-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-dttext-read-dttext-manual.https.html
deleted file mode 100644
index 2930b471..0000000
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-dttext-read-dttext-manual.https.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Async Clipboard write (dt/text) -> read (dt/text) tests</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-promise_test(async t => {
-  const input = "Clipboard write (dt/text) -> read (dt/text) test data";
-  const dt = new DataTransfer();
-  dt.items.add(input, "text/plain");
-
-  await navigator.clipboard.write(dt);
-  const output = await navigator.clipboard.read();
-
-  assert_equals(output.items.length, 1);
-  const result_promise = new Promise(resolve => {
-    output.items[0].getAsString(resolve);
-  });
-  const string_output = await result_promise;
-  assert_equals(string_output, input);
-}, "Verify write and read clipboard (DataTransfer/text)");
-</script>
-Note: This is a manual test because it writes/reads to the shared system
-clipboard and thus cannot be run async with other tests that might interact
-with the clipboard.
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-dttext-read-text-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-dttext-read-text-manual.https.html
deleted file mode 100644
index 1b178696..0000000
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-dttext-read-text-manual.https.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Async Clipboard write (dt/text) -> readText tests</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-promise_test(async t => {
-  const input = "Clipboard write (dt/text) -> readText test data";
-  const dt = new DataTransfer();
-  dt.items.add(input, "text/plain");
-
-  await navigator.clipboard.write(dt);
-  const output = await navigator.clipboard.readText();
-
-  assert_equals(output, input);
-}, "Verify write and read clipboard (DataTransfer/text)");
-</script>
-Note: This is a manual test because it writes/reads to the shared system
-clipboard and thus cannot be run async with other tests that might interact
-with the clipboard.
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image-manual.https.html
index 6117e4697..ee90e7e 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-image-read-image-manual.https.html
@@ -39,8 +39,10 @@
 promise_test(async t => {
   const input = await loadBlob('resources/greenbox.png');
 
-  await navigator.clipboard.writeImageExperimental(input);
-  const output = await navigator.clipboard.readImageExperimental();
+  assert_equals(input.type, "image/png");
+  await navigator.clipboard.write(input);
+  const output = await navigator.clipboard.read();
+  assert_equals(output.type, "image/png");
 
   document.getElementById('image-on-clipboard').src =
       window.URL.createObjectURL(output);
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-blobtext-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-blobtext-manual.https.html
new file mode 100644
index 0000000..69f72db8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-blobtext-manual.https.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Async Clipboard writeText -> read (Blob/text) tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+async function readWriteTest(textInput) {
+  promise_test(async t => {
+    await navigator.clipboard.writeText(textInput);
+    const blobOutput = await navigator.clipboard.read();
+    assert_equals(blobOutput.type, "text/plain");
+
+    const textOutput = await (new Response(blobOutput)).text();
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
+
+readWriteTest("Clipboard write text -> read (Blob/text) test");
+readWriteTest("non-Latin1 text encoding test データ");
+</script>
+<p>
+  Note: This is a manual test because it writes/reads to the shared system
+  clipboard and thus cannot be run async with other tests that might interact
+  with the clipboard.
+</p>
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-dttext-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-dttext-manual.https.html
deleted file mode 100644
index 9f524b9..0000000
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-dttext-manual.https.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>Async Clipboard writeText -> read (dt/text) tests</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script>
-promise_test(async t => {
-  const input = "Clipboard writeText -> read (dt/text) test data";
-
-  await navigator.clipboard.writeText(input);
-  const output = await navigator.clipboard.read();
-
-  assert_equals(output.items.length, 1);
-  const result_promise = new Promise(resolve => {
-    output.items[0].getAsString(resolve);
-  });
-  const string_output = await result_promise;
-  assert_equals(string_output, input);
-}, "Verify write and read clipboard (DOMString)");
-</script>
-Note: This is a manual test because it writes/reads to the shared system
-clipboard and thus cannot be run async with other tests that might interact
-with the clipboard.
diff --git a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-text-manual.https.html b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-text-manual.https.html
index 3a3922e..496bdd7 100644
--- a/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-text-manual.https.html
+++ b/third_party/blink/web_tests/external/wpt/clipboard-apis/async-write-text-read-text-manual.https.html
@@ -4,15 +4,20 @@
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script>
-promise_test(async t => {
-  const input = "Clipboard writeText -> readText test data";
+async function readWriteTest(textInput) {
+  promise_test(async t => {
+    await navigator.clipboard.writeText(textInput);
+    const textOutput = await navigator.clipboard.readText();
 
-  await navigator.clipboard.writeText(input);
-  const output = await navigator.clipboard.readText();
+    assert_equals(textOutput, textInput);
+  }, "Verify write and read clipboard given text: " + textInput);
+}
 
-  assert_equals(output, input);
-}, "Verify write and read clipboard (DOMString)");
+readWriteTest("Clipboard write text -> read text test");
+readWriteTest("non-Latin1 text encoding test データ");
 </script>
-Note: This is a manual test because it writes/reads to the shared system
-clipboard and thus cannot be run async with other tests that might interact
-with the clipboard.
+<p>
+  Note: This is a manual test because it writes/reads to the shared system
+  clipboard and thus cannot be run async with other tests that might interact
+  with the clipboard.
+</p>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-report-only.https.html b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-report-only.https.html
new file mode 100644
index 0000000..11913a2
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-report-only.https.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+    <script src='/resources/testdriver.js'></script>
+    <script src="/resources/testdriver-vendor.js"></script>
+  </head>
+  <body>
+    <div id='fs'></div>
+    <script>
+var check_report_format = ([reports, observer]) => {
+  let report = reports[0];
+  assert_equals(report.type, "feature-policy-violation");
+  assert_equals(report.body.featureId, "serial");
+  assert_equals(report.body.disposition, "report");
+};
+
+promise_test(async t => {
+  const report = new Promise(resolve => {
+    new ReportingObserver((reports, observer) => resolve([reports, observer]),
+                          {types: ['feature-policy-violation']}).observe();
+  });
+
+  await test_driver.bless('Activate document for serial.requestPort');
+  try {
+    await navigator.serial.requestPort({filters: []});
+    assert_unreached('requestPort() call should fail when no port is selected.');
+  } catch (e) {
+    assert_equals(e.code, DOMException.NOT_FOUND_ERR);
+  }
+  check_report_format(await report);
+}, "requestPort in serial report only mode");
+
+promise_test(async t => {
+  const report = new Promise(resolve => {
+    new ReportingObserver((reports, observer) => resolve([reports, observer]),
+                          {types: ['feature-policy-violation']}).observe();
+  });
+
+  await navigator.serial.getPorts();
+  check_report_format(await report);
+}, "getPorts in serial report only mode");
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-report-only.https.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-report-only.https.html.headers
new file mode 100644
index 0000000..d408ccf
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-report-only.https.html.headers
@@ -0,0 +1 @@
+Feature-Policy-Report-Only: serial 'none'
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-reporting.https.html b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-reporting.https.html
new file mode 100644
index 0000000..827bc893
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-reporting.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script src='/resources/testharness.js'></script>
+    <script src='/resources/testharnessreport.js'></script>
+    <script src='/resources/testdriver.js'></script>
+    <script src="/resources/testdriver-vendor.js"></script>
+  </head>
+  <body>
+    <script>
+var check_report_format = ([reports, observer]) => {
+  let report = reports[0];
+  assert_equals(report.type, "feature-policy-violation");
+  assert_equals(report.url, document.location.href);
+  assert_equals(report.body.featureId, "serial");
+  assert_equals(report.body.sourceFile, document.location.href);
+  assert_equals(typeof report.body.lineNumber, "number");
+  assert_equals(typeof report.body.columnNumber, "number");
+  assert_equals(report.body.disposition, "enforce");
+};
+
+promise_test(async t => {
+  const report = new Promise(resolve => {
+    new ReportingObserver((reports, observer) => resolve([reports, observer]),
+                          {types: ['feature-policy-violation']}).observe();
+  });
+
+  await test_driver.bless('Activate document for serial.requestPort');
+  try {
+    await navigator.serial.requestPort({ filters: [] });
+    assert_unreached("Serial port access should not be allowed in this document.");
+  } catch (e) {
+    assert_equals(e.code, DOMException.SECURITY_ERR);
+  }
+  check_report_format(await report);
+}, "requestPort in serial reporting mode");
+
+promise_test(async t => {
+  const report = new Promise(resolve => {
+    new ReportingObserver((reports, observer) => resolve([reports, observer]),
+                          {types: ['feature-policy-violation']}).observe();
+  });
+
+  try {
+    await navigator.serial.getPorts();
+    assert_unreached("Serial port access should not be allowed in this document.");
+  } catch (e) {
+    assert_equals(e.code, DOMException.SECURITY_ERR);
+  }
+  check_report_format(await report);
+}, "getPorts in serial reporting mode");
+    </script>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-reporting.https.html.headers b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-reporting.https.html.headers
new file mode 100644
index 0000000..be3e6af
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/reporting/serial-reporting.https.html.headers
@@ -0,0 +1 @@
+Feature-Policy: serial 'none'
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial-worker.html b/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial-worker.html
new file mode 100644
index 0000000..9e6a7d02
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial-worker.html
@@ -0,0 +1,10 @@
+<script>
+'use strict';
+
+let worker = new Worker('feature-policy-serial-worker.js');
+
+worker.onmessage = event => {
+  window.parent.postMessage(event.data, '*');
+};
+worker.postMessage({ type: 'ready' });
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial-worker.js b/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial-worker.js
new file mode 100644
index 0000000..2e8e6f5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial-worker.js
@@ -0,0 +1,14 @@
+'use strict';
+
+// Dedicated worker
+if (typeof postMessage === 'function') {
+  onmessage = event => {
+    switch(event.data.type) {
+      case 'ready':
+        navigator.serial.getPorts().then(
+            () => postMessage({ enabled: true }),
+            error => postMessage ({ enabled: false }));
+        break;
+    }
+  };
+}
diff --git a/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial.html b/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial.html
new file mode 100644
index 0000000..caf716d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/feature-policy/resources/feature-policy-serial.html
@@ -0,0 +1,9 @@
+<script>
+'use strict';
+
+navigator.serial.getPorts().then(ports => {
+  window.parent.postMessage({ enabled: true }, '*');
+}, error => {
+  window.parent.postMessage({ enabled: false }, '*');
+});
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html
deleted file mode 100644
index 314a7035..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain_setter_null.tentative.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<!DOCTYPE html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<body>
-<!-- SEKRITS! -->
-<input id="sekrit" value="omg!">
-
-<script>
-  function postMessageToFrame(frame, message) {
-    return new Promise(resolve => {
-      var c = new MessageChannel();
-      c.port1.onmessage = e => {
-        resolve({ data: e.data, frame: frame })
-      };
-      frame.contentWindow.postMessage(message, '*', [c.port2]);
-    });
-  }
-
-  function createFrame() {
-    return new Promise(resolve => {
-      var i = document.createElement('iframe');
-      i.src = "./support/document_domain_frame.html";
-      window.addEventListener('message', m => {
-        if (m.source == i.contentWindow)
-          resolve(i);
-      });
-      document.body.appendChild(i);
-    });
-  }
-
-  promise_test(t => {
-    return createFrame()
-      .then(f => postMessageToFrame(f, 'poke-at-parent'))
-      .then(result => {
-        assert_equals(result.data, document.querySelector('#sekrit').value);
-        result.frame.remove();
-      });
-  }, "Access allowed with no 'document.domain' modification. (Sanity check)");
-
-  promise_test(t => {
-    return createFrame()
-      .then(f => postMessageToFrame(f, { domain: null }))
-      .then(result => {
-        assert_equals(result.data, 'Done');
-        return postMessageToFrame(result.frame, 'poke-at-parent')
-          .then(result => {
-            assert_equals(result.data, 'SecurityError');
-            result.frame.remove();
-          });
-      });
-  }, "No access when frame sets a `null` 'document.domain'.");
-
-  promise_test(t => {
-    return createFrame()
-      .then(f => {
-        document.domain = null;
-        assert_equals(document.domain, "null");
-        return postMessageToFrame(f, 'poke-at-parent');
-      })
-      .then(result => {
-        assert_equals(result.data, 'SecurityError');
-        result.frame.remove();
-      });
-  }, "No access when parent sets a `null` 'document.domain'.");
-
-  promise_test(t => {
-    return createFrame()
-      .then(f => {
-        document.domain = null;
-        assert_equals(document.domain, "null");
-        return postMessageToFrame(f, { domain: null });
-      })
-      .then(result => {
-        assert_equals(result.data, 'Done');
-        return postMessageToFrame(result.frame, 'poke-at-parent')
-          .then(result => {
-            assert_equals(result.data, 'SecurityError');
-            result.frame.remove();
-          });
-      });
-  }, "No access when both sides set a `null` 'document.domain'.");
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_frame.html b/third_party/blink/web_tests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_frame.html
deleted file mode 100644
index 42e8137..0000000
--- a/third_party/blink/web_tests/external/wpt/html/browsers/origin/relaxing-the-same-origin-restriction/support/document_domain_frame.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<script>
-  window.addEventListener('message', e => {
-    if (e.data.domain !== undefined) {
-      try {
-        document.domain = e.data.domain;
-        e.ports[0].postMessage('Done');
-      } catch(error) {
-        e.ports[0].postMessage(error.name);
-      }
-    } else if (e.data == 'poke-at-parent') {
-      try {
-        var sekrit = window.parent.document.body.querySelector('#sekrit').value;
-        e.ports[0].postMessage(sekrit);
-      } catch(error) {
-        e.ports[0].postMessage(error.name);
-      }
-    }
-  });
-  window.parent.postMessage('Hi!', '*');
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/serial/resources/serial-allowed-by-feature-policy-worker.js b/third_party/blink/web_tests/external/wpt/serial/resources/serial-allowed-by-feature-policy-worker.js
new file mode 100644
index 0000000..46c338e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/resources/serial-allowed-by-feature-policy-worker.js
@@ -0,0 +1,14 @@
+'use strict';
+
+importScripts('/resources/testharness.js');
+
+let workerType;
+
+if (typeof postMessage === 'function') {
+  workerType = 'dedicated';
+}
+
+promise_test(() => navigator.serial.getPorts(),
+    `Inherited header feature policy allows ${workerType} workers.`);
+
+done();
diff --git a/third_party/blink/web_tests/external/wpt/serial/resources/serial-disabled-by-feature-policy-worker.js b/third_party/blink/web_tests/external/wpt/serial/resources/serial-disabled-by-feature-policy-worker.js
new file mode 100644
index 0000000..b64b1a8
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/resources/serial-disabled-by-feature-policy-worker.js
@@ -0,0 +1,17 @@
+'use strict';
+
+importScripts('/resources/testharness.js');
+
+const header = 'Feature-Policy header {"serial" : []}';
+let workerType;
+
+if (typeof postMessage === 'function') {
+  workerType = 'dedicated';
+}
+
+promise_test(() => navigator.serial.getPorts().then(
+        () => assert_unreached('expected promise to reject with SecurityError'),
+        error => assert_equals(error.name, 'SecurityError')),
+    `Inherited ${header} disallows ${workerType} workers.`);
+
+done();
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html
new file mode 100644
index 0000000..7c3a88d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<body>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/feature-policy/resources/featurepolicy.js></script>
+<script>
+'use strict';
+const relative_path = '/feature-policy/resources/feature-policy-serial.html';
+const base_src = '/feature-policy/resources/redirect-on-load.html#';
+const relative_worker_frame_path =
+    '/feature-policy/resources/feature-policy-serial-worker.html';
+const sub = 'https://{{domains[www]}}:{{ports[https][0]}}';
+const same_origin_src = base_src + relative_path;
+const cross_origin_src = base_src + sub + relative_path;
+const same_origin_worker_frame_src = base_src + relative_worker_frame_path;
+const cross_origin_worker_frame_src = base_src + sub +
+    relative_worker_frame_path;
+const header = 'Feature-Policy allow="serial"';
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, same_origin_src,
+      expect_feature_available_default, 'serial');
+}, header + ' allows same-origin relocation.');
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, same_origin_worker_frame_src,
+      expect_feature_available_default, 'serial');
+}, header + ' allows workers in same-origin relocation.');
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, cross_origin_src,
+      expect_feature_unavailable_default, 'serial');
+}, header + ' disallows cross-origin relocation.');
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, cross_origin_worker_frame_src,
+      expect_feature_unavailable_default, 'serial');
+}, header + ' disallows workers in cross-origin relocation.');
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy-attribute.https.sub.html b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy-attribute.https.sub.html
new file mode 100644
index 0000000..1420c5c0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy-attribute.https.sub.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<body>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/feature-policy/resources/featurepolicy.js></script>
+<script>
+'use strict';
+const sub = 'https://{{domains[www]}}:{{ports[https][0]}}';
+const same_origin_src = '/feature-policy/resources/feature-policy-serial.html';
+const cross_origin_src = sub + same_origin_src;
+const same_origin_worker_frame_src =
+    '/feature-policy/resources/feature-policy-serial-worker.html';
+const cross_origin_worker_frame_src = sub + same_origin_worker_frame_src;
+const feature_name = 'Feature policy "serial"';
+const header = 'allow="serial" attribute';
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, same_origin_src,
+      expect_feature_available_default, 'serial');
+}, feature_name + ' can be enabled in same-origin iframe using ' + header);
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, same_origin_worker_frame_src,
+      expect_feature_available_default, 'serial');
+}, feature_name + ' can be enabled in a worker in same-origin iframe using ' +
+    header);
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, cross_origin_src,
+      expect_feature_available_default, 'serial');
+}, feature_name + ' can be enabled in cross-origin iframe using ' + header);
+
+async_test(t => {
+  test_feature_availability(
+      'serial.getPorts()', t, cross_origin_worker_frame_src,
+      expect_feature_available_default, 'serial');
+}, feature_name + ' can be enabled in a worker in cross-origin iframe using ' +
+    header);
+
+fetch_tests_from_worker(new Worker(
+    'resources/serial-allowed-by-feature-policy-worker.js'));
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html
new file mode 100644
index 0000000..316256b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<body>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/feature-policy/resources/featurepolicy.js></script>
+<script>
+'use strict';
+const sub = 'https://{{domains[www]}}:{{ports[https][0]}}';
+const same_origin_src = '/feature-policy/resources/feature-policy-serial.html';
+const cross_origin_src = sub + same_origin_src;
+const same_origin_worker_frame_src =
+    '/feature-policy/resources/feature-policy-serial-worker.html';
+const cross_origin_worker_frame_src = sub + same_origin_worker_frame_src;
+const header = 'Feature-Policy header {"serial" : ["*"]}';
+
+promise_test(
+    () => navigator.serial.getPorts(),
+    header + ' allows the top-level document.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, same_origin_src,
+      expect_feature_available_default);
+}, header + ' allows same-origin iframes.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, same_origin_worker_frame_src,
+      expect_feature_available_default);
+}, header + ' allows workers in same-origin iframes.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, cross_origin_src,
+      expect_feature_available_default);
+}, header + ' allows cross-origin iframes.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t,
+      cross_origin_worker_frame_src,
+      expect_feature_available_default);
+}, header + ' allows workers in cross-origin iframes.');
+
+fetch_tests_from_worker(new Worker(
+    'resources/serial-allowed-by-feature-policy-worker.js'));
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html.headers b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html.headers
new file mode 100644
index 0000000..113ce29
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serial-allowed-by-feature-policy.https.sub.html.headers
@@ -0,0 +1 @@
+Feature-Policy: serial *
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-default-feature-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/serial/serial-default-feature-policy.https.sub.html
new file mode 100644
index 0000000..61a872f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serial-default-feature-policy.https.sub.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<body>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/feature-policy/resources/featurepolicy.js></script>
+<script>
+'use strict';
+var same_origin_src = '/feature-policy/resources/feature-policy-serial.html';
+var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+  same_origin_src;
+var header = 'Default "serial" feature policy ["self"]';
+
+promise_test(
+    () => navigator.serial.getPorts(),
+    header + ' allows the top-level document.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, same_origin_src,
+      expect_feature_available_default);
+}, header + ' allows same-origin iframes.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, cross_origin_src,
+      expect_feature_unavailable_default);
+}, header + ' disallows cross-origin iframes.');
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-disabled-by-feature-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/serial/serial-disabled-by-feature-policy.https.sub.html
new file mode 100644
index 0000000..cddf157
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serial-disabled-by-feature-policy.https.sub.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/feature-policy/resources/featurepolicy.js"></script>
+<script>
+'use strict';
+const sub = 'https://{{domains[www]}}:{{ports[https][0]}}';
+const same_origin_src = '/feature-policy/resources/feature-policy-serial.html';
+const cross_origin_src = sub + same_origin_src;
+const same_origin_worker_frame_src =
+    '/feature-policy/resources/feature-policy-serial-worker.html';
+const cross_origin_worker_frame_src = sub + same_origin_worker_frame_src;
+const header = 'Feature-Policy header {"serial" : []}';
+
+promise_test(() => {
+  return navigator.serial.getPorts().then(() => {
+    assert_unreached('expected promise to reject with SecurityError');
+  }, error => {
+    assert_equals(error.name, 'SecurityError');
+  });
+}, header + ' disallows getPorts in the top-level document.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, same_origin_src,
+      expect_feature_unavailable_default);
+}, header + ' disallows same-origin iframes.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, same_origin_worker_frame_src,
+      expect_feature_unavailable_default);
+}, header + ' disallows workers in same-origin iframes.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t, cross_origin_src,
+      expect_feature_unavailable_default);
+}, header + ' disallows cross-origin iframes.');
+
+async_test(t => {
+  test_feature_availability('serial.getPorts()', t,
+      cross_origin_worker_frame_src,
+      expect_feature_unavailable_default);
+}, header + ' disallows workers in cross-origin iframes.');
+
+fetch_tests_from_worker(new Worker(
+    'resources/serial-disabled-by-feature-policy-worker.js'));
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/serial/serial-disabled-by-feature-policy.https.sub.html.headers b/third_party/blink/web_tests/external/wpt/serial/serial-disabled-by-feature-policy.https.sub.html.headers
new file mode 100644
index 0000000..be3e6af
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/serial/serial-disabled-by-feature-policy.https.sub.html.headers
@@ -0,0 +1 @@
+Feature-Policy: serial 'none'
diff --git a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
index 5af34e3..6e0c787 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webxr/idlharness.https.window-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 215 tests; 195 PASS, 20 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 215 tests; 199 PASS, 16 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS idl_test setup
 PASS Partial interface Navigator: original interface defined
 PASS Partial dictionary WebGLContextAttributes: original dictionary defined
@@ -74,7 +74,7 @@
 PASS XRReferenceSpace interface: existence and properties of interface prototype object
 PASS XRReferenceSpace interface: existence and properties of interface prototype object's "constructor" property
 PASS XRReferenceSpace interface: existence and properties of interface prototype object's @@unscopables property
-FAIL XRReferenceSpace interface: attribute originOffset assert_true: The prototype object must have a property "originOffset" expected true got false
+PASS XRReferenceSpace interface: attribute originOffset
 PASS XRReferenceSpace interface: attribute onreset
 PASS XRStationaryReferenceSpace interface: existence and properties of interface object
 PASS XRStationaryReferenceSpace interface object length
@@ -105,7 +105,7 @@
 PASS XRView interface: attribute eye
 PASS XRView interface: attribute projectionMatrix
 PASS XRView interface: attribute viewMatrix
-FAIL XRView interface: attribute transform assert_true: The prototype object must have a property "transform" expected true got false
+PASS XRView interface: attribute transform
 PASS XRViewport interface: existence and properties of interface object
 PASS XRViewport interface object length
 PASS XRViewport interface object name
@@ -140,7 +140,7 @@
 PASS XRViewerPose interface: existence and properties of interface prototype object
 PASS XRViewerPose interface: existence and properties of interface prototype object's "constructor" property
 PASS XRViewerPose interface: existence and properties of interface prototype object's @@unscopables property
-FAIL XRViewerPose interface: attribute transform assert_true: The prototype object must have a property "transform" expected true got false
+PASS XRViewerPose interface: attribute transform
 PASS XRViewerPose interface: attribute views
 PASS XRInputSource interface: existence and properties of interface object
 PASS XRInputSource interface object length
@@ -158,7 +158,7 @@
 PASS XRInputPose interface: existence and properties of interface prototype object's @@unscopables property
 PASS XRInputPose interface: attribute emulatedPosition
 PASS XRInputPose interface: attribute targetRay
-FAIL XRInputPose interface: attribute gripTransform assert_true: The prototype object must have a property "gripTransform" expected true got false
+PASS XRInputPose interface: attribute gripTransform
 PASS XRLayer interface: existence and properties of interface object
 PASS XRLayer interface object length
 PASS XRLayer interface object name
diff --git a/third_party/blink/web_tests/external/wpt/webxr/xrSession_identity_referenceSpace.https.html b/third_party/blink/web_tests/external/wpt/webxr/xrSession_identity_referenceSpace.https.html
index 6f4f1e8..6cb2501 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/xrSession_identity_referenceSpace.https.html
+++ b/third_party/blink/web_tests/external/wpt/webxr/xrSession_identity_referenceSpace.https.html
@@ -36,7 +36,7 @@
                 let pose = xrFrame.getViewerPose(referenceSpace);
                 assert_not_equals(pose, null);
 
-                let poseMatrix = pose.poseModelMatrix;
+                let poseMatrix = pose.transform.matrix;
                 assert_not_equals(poseMatrix, null);
 
                 for(let i = 0; i < poseMatrix.length; i++) {
@@ -61,7 +61,7 @@
                 let pose = xrFrame.getViewerPose(referenceSpace);
                 assert_not_equals(pose, null);
 
-                let poseMatrix = pose.poseModelMatrix;
+                let poseMatrix = pose.transform.matrix;
                 assert_not_equals(poseMatrix, null);
 
                 for(let i = 0; i < poseMatrix.length; i++) {
diff --git a/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_data_valid.https.html b/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_data_valid.https.html
index f873a11..41801bc 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_data_valid.https.html
+++ b/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_data_valid.https.html
@@ -44,7 +44,7 @@
 
             assert_not_equals(viewerPose, null);
             for(let i = 0; i < identityMatrix.length; i++) {
-              assert_equals(viewerPose.poseModelMatrix[i], identityMatrix[i]);
+              assert_equals(viewerPose.transform.matrix[i], identityMatrix[i]);
             }
 
             assert_not_equals(viewerPose.views, null);
diff --git a/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html b/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html
index ca6a7175..618dc13 100644
--- a/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html
+++ b/third_party/blink/web_tests/external/wpt/webxr/xrSession_requestAnimationFrame_getViewerPose.https.html
@@ -52,7 +52,7 @@
                 let pose = vrFrame.getViewerPose(referenceSpace);
                 assert_not_equals(pose, null);
 
-                let poseMatrix = pose.poseModelMatrix;
+                let poseMatrix = pose.transform.matrix;
                 assert_not_equals(poseMatrix, null);
 
                 for(let i = 0; i < poseMatrix.length; i++) {
diff --git a/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect-expected.txt b/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect-expected.txt
index dc23656..7a7b062 100644
--- a/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect-expected.txt
+++ b/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect-expected.txt
@@ -27,9 +27,9 @@
 PASS popupWindow.adjustWindowRect(30, 10, 30, 10).toString() is "Rectangle(50,10,30,10)"
 PASS popupWindow.adjustWindowRect(30, 10, 30, 10).toString() is "Rectangle(50,10,30,10)"
 PASS popupWindow.adjustWindowRect(30, 10, 30, 10).toString() is "Rectangle(60,10,30,10)"
-PASS popupWindow.adjustWindowRect(30, 10, 30, 10).toString() is "Rectangle(70,10,30,10)"
 PASS popupWindow.adjustWindowRect(30, 10, 30, 10).toString() is "Rectangle(80,10,30,10)"
 PASS popupWindow.adjustWindowRect(30, 10, 30, 10).toString() is "Rectangle(90,10,30,10)"
+PASS popupWindow.adjustWindowRect(30, 10, 30, 10).toString() is "Rectangle(100,10,30,10)"
 Move anchor element along the vertical axis. Open popup that is too tall.
 PASS popupWindow.adjustWindowRect(30, 1000, 30, 10).toString() is "Rectangle(0,-10,30,60)"
 PASS popupWindow.adjustWindowRect(30, 1000, 30, 10).toString() is "Rectangle(0,0,30,60)"
diff --git a/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect.html b/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect.html
index 62420e5..afe7b618 100644
--- a/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect.html
+++ b/third_party/blink/web_tests/fast/forms/page-popup/page-popup-adjust-rect.html
@@ -112,14 +112,14 @@
     shouldBeEqualToString('popupWindow.adjustWindowRect(30, 10, 30, 10).toString()', 'Rectangle(60,10,30,10)');
 
     popupWindow.global.params.anchorRectInScreen = makeRect(80, 0, 20, 10);
-    shouldBeEqualToString('popupWindow.adjustWindowRect(30, 10, 30, 10).toString()', 'Rectangle(70,10,30,10)');
-
-    popupWindow.global.params.anchorRectInScreen = makeRect(90, 0, 20, 10);
     shouldBeEqualToString('popupWindow.adjustWindowRect(30, 10, 30, 10).toString()', 'Rectangle(80,10,30,10)');
 
-    popupWindow.global.params.anchorRectInScreen = makeRect(100, 0, 20, 10);
+    popupWindow.global.params.anchorRectInScreen = makeRect(90, 0, 20, 10);
     shouldBeEqualToString('popupWindow.adjustWindowRect(30, 10, 30, 10).toString()', 'Rectangle(90,10,30,10)');
 
+    popupWindow.global.params.anchorRectInScreen = makeRect(100, 0, 20, 10);
+    shouldBeEqualToString('popupWindow.adjustWindowRect(30, 10, 30, 10).toString()', 'Rectangle(100,10,30,10)');
+
     debug("Move anchor element along the vertical axis. Open popup that is too tall.");
 
     popupWindow.global.params.anchorRectInScreen = makeRect(0, -20, 20, 10);
diff --git a/third_party/blink/web_tests/http/tests/clipboard/async-write-image-read-image.html b/third_party/blink/web_tests/http/tests/clipboard/async-write-image-read-image.html
index 0f82370..fa7e522 100644
--- a/third_party/blink/web_tests/http/tests/clipboard/async-write-image-read-image.html
+++ b/third_party/blink/web_tests/http/tests/clipboard/async-write-image-read-image.html
@@ -43,8 +43,10 @@
 
   const input = await loadBlob('resources/greenbox.png');
 
-  await navigator.clipboard.writeImageExperimental(input);
-  const output = await navigator.clipboard.readImageExperimental();
+  assert_equals(input.type, "image/png");
+  await navigator.clipboard.write(input);
+  const output = await navigator.clipboard.read();
+  assert_equals(output.type, "image/png");
 
   document.getElementById('image-on-clipboard').src =
       window.URL.createObjectURL(output);
diff --git a/third_party/blink/web_tests/http/tests/security/document-domain-invalid.html b/third_party/blink/web_tests/http/tests/security/document-domain-invalid.html
index 893dd017..91fd118 100644
--- a/third_party/blink/web_tests/http/tests/security/document-domain-invalid.html
+++ b/third_party/blink/web_tests/http/tests/security/document-domain-invalid.html
@@ -9,6 +9,15 @@
             assert_equals(document.domain, '127.0.0.1');
             assert_throws('SecurityError',
                           function () {
+                            document.domain = null;
+                          });
+            assert_equals(document.domain, '127.0.0.1');
+        }, 'Setting `document.domain` to null fails.');
+
+        test(function () {
+            assert_equals(document.domain, '127.0.0.1');
+            assert_throws('SecurityError',
+                          function () {
                             document.domain = '';
                           });
             assert_equals(document.domain, '127.0.0.1');
diff --git a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
index 544529b..8d09ebc 100644
--- a/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
+++ b/third_party/blink/web_tests/webexposed/feature-policy-features-expected.txt
@@ -21,6 +21,7 @@
 oversized-images
 payment
 picture-in-picture
+serial
 speaker
 sync-script
 sync-xhr
diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
index e3c19ad..a7687a8 100644
--- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt
@@ -1063,10 +1063,8 @@
     attribute @@toStringTag
     method constructor
     method read
-    method readImageExperimental
     method readText
     method write
-    method writeImageExperimental
     method writeText
 interface ClipboardEvent : Event
     attribute @@toStringTag
@@ -10408,7 +10406,7 @@
 interface XRInputPose
     attribute @@toStringTag
     getter emulatedPosition
-    getter gripMatrix
+    getter gripTransform
     getter targetRay
     method constructor
 interface XRInputSource
@@ -10437,8 +10435,10 @@
 interface XRReferenceSpace : XRSpace
     attribute @@toStringTag
     getter onreset
+    getter originOffset
     method constructor
     setter onreset
+    setter originOffset
 interface XRRenderState
     attribute @@toStringTag
     getter baseLayer
@@ -10496,11 +10496,12 @@
     attribute @@toStringTag
     getter eye
     getter projectionMatrix
+    getter transform
     getter viewMatrix
     method constructor
 interface XRViewerPose
     attribute @@toStringTag
-    getter poseModelMatrix
+    getter transform
     getter views
     method constructor
 interface XRViewport
diff --git a/third_party/blink/web_tests/xr/getInputPose_hand.html b/third_party/blink/web_tests/xr/getInputPose_hand.html
index 6ac83f2..1acb9b8c 100644
--- a/third_party/blink/web_tests/xr/getInputPose_hand.html
+++ b/third_party/blink/web_tests/xr/getInputPose_hand.html
@@ -70,10 +70,11 @@
         t.step( () => {
           // When a grip matrix is present but no pointer offset is specified,
           // the grip and pointer matrices should be the same.
-          assert_matrices_approx_equal(input_pose.gripMatrix, VALID_GRIP,
+          assert_not_equals(input_pose.gripTransform, null);
+          assert_matrices_approx_equal(input_pose.gripTransform.matrix, VALID_GRIP,
             FLOAT_EPSILON, "Grip matrix is not equal to input.");
           assert_matrices_approx_equal(input_pose.targetRay.transformMatrix,
-            input_pose.gripMatrix, FLOAT_EPSILON,
+            input_pose.gripTransform.matrix, FLOAT_EPSILON,
             "Grip matrix is not equal to target ray matrix.");
         });
 
@@ -91,7 +92,8 @@
           // When a grip matrix and pointer offset are specified,
           // pointer matrix should be grip matrix multiplied with the pointer
           // offset.
-          assert_matrices_approx_equal(input_pose.gripMatrix, VALID_GRIP,
+          assert_not_equals(input_pose.gripTransform, null);
+          assert_matrices_approx_equal(input_pose.gripTransform.matrix, VALID_GRIP,
             FLOAT_EPSILON, "Grip matrix is not equal to input valid grip.");
           assert_matrices_approx_equal(input_pose.targetRay.transformMatrix,
             VALID_GRIP_WITH_POINTER_OFFSET, FLOAT_EPSILON,
diff --git a/third_party/blink/web_tests/xr/getInputPose_ray.html b/third_party/blink/web_tests/xr/getInputPose_ray.html
index bc4ad90..f6ad40b 100644
--- a/third_party/blink/web_tests/xr/getInputPose_ray.html
+++ b/third_party/blink/web_tests/xr/getInputPose_ray.html
@@ -50,8 +50,9 @@
         let input_pose = xrFrame.getInputPose(source, referenceSpace);
 
         t.step( () => {
+          assert_not_equals(input_pose.gripTransform, null);
           assert_matrices_approx_equal(input_pose.targetRay.transformMatrix,
-            input_pose.gripMatrix, FLOAT_EPSILON,
+            input_pose.gripTransform.matrix, FLOAT_EPSILON,
             "Target ray matrix is incorrect.");
 
           assert_equals(input_pose.targetRay.origin.x, 4.0);
diff --git a/third_party/blink/web_tests/xr/xrStationaryReferenceSpace_floorlevel_updates.html b/third_party/blink/web_tests/xr/xrStationaryReferenceSpace_floorlevel_updates.html
index 0b77442..f8f82b3 100644
--- a/third_party/blink/web_tests/xr/xrStationaryReferenceSpace_floorlevel_updates.html
+++ b/third_party/blink/web_tests/xr/xrStationaryReferenceSpace_floorlevel_updates.html
@@ -44,7 +44,7 @@
         t.step( () => {
           let pose = xrFrame.getViewerPose(referenceSpace);
 
-          let poseMatrix = pose.poseModelMatrix;
+          let poseMatrix = pose.transform.matrix;
           assert_approx_equals(poseMatrix[12], 0.0, FLOAT_EPSILON);
           assert_greater_than(poseMatrix[13], 1.0);
           assert_approx_equals(poseMatrix[14], 0.0, FLOAT_EPSILON);
@@ -62,7 +62,7 @@
           let pose = xrFrame.getViewerPose(referenceSpace);
           assert_not_equals(pose, null);
 
-          let poseMatrix = pose.poseModelMatrix;
+          let poseMatrix = pose.transform.matrix;
           assert_matrices_approx_equal(poseMatrix, VALID_STAGE_TRANSFORM);
         });
 
diff --git a/third_party/inspector_protocol/BUILD.gn b/third_party/inspector_protocol/BUILD.gn
index 9631371..6b82c845 100644
--- a/third_party/inspector_protocol/BUILD.gn
+++ b/third_party/inspector_protocol/BUILD.gn
@@ -15,6 +15,8 @@
     "encoding/platform.h",
     "encoding/span.h",
     "encoding/status.h",
+    "encoding/str_util.cc",
+    "encoding/str_util.h",
   ]
 }
 
diff --git a/third_party/inspector_protocol/README.chromium b/third_party/inspector_protocol/README.chromium
index 606a31f..b7d510e 100644
--- a/third_party/inspector_protocol/README.chromium
+++ b/third_party/inspector_protocol/README.chromium
@@ -2,7 +2,7 @@
 Short Name: inspector_protocol
 URL: https://chromium.googlesource.com/deps/inspector_protocol/
 Version: 0
-Revision: 8dfd1432319592c9ed70676b6cc166ee98025664
+Revision: dfaf19b7350529d9d454ae79b6747ee57cd1c6d4
 License: BSD
 License File: LICENSE
 Security Critical: no
diff --git a/third_party/inspector_protocol/README.md b/third_party/inspector_protocol/README.md
index 4eff433..da3f93f 100644
--- a/third_party/inspector_protocol/README.md
+++ b/third_party/inspector_protocol/README.md
@@ -26,3 +26,8 @@
     gn gen out/Release
     ninja -C out/Release json_parser_test
     out/Release/json_parser_test
+
+You'll probably also need to install g++, since Clang uses this to find the
+standard C++ headers. E.g.,
+
+    sudo apt-get install g++-8
diff --git a/third_party/inspector_protocol/code_generator.py b/third_party/inspector_protocol/code_generator.py
index bee9cce..0ba7276 100755
--- a/third_party/inspector_protocol/code_generator.py
+++ b/third_party/inspector_protocol/code_generator.py
@@ -623,7 +623,7 @@
         lib_templates_dir = os.path.join(module_path, "lib")
         # Note these should be sorted in the right order.
         # TODO(dgozman): sort them programmatically based on commented includes.
-        lib_h_templates = [
+        protocol_h_templates = [
             "ErrorSupport_h.template",
             "Values_h.template",
             "Object_h.template",
@@ -634,7 +634,7 @@
             "Parser_h.template",
         ]
 
-        lib_cpp_templates = [
+        protocol_cpp_templates = [
             "Protocol_cpp.template",
             "ErrorSupport_cpp.template",
             "Values_cpp.template",
@@ -649,6 +649,14 @@
             "FrontendChannel_h.template",
         ]
 
+        base_string_adapter_h_templates = [
+            "base_string_adapter_h.template",
+        ]
+
+        base_string_adapter_cc_templates = [
+            "base_string_adapter_cc.template",
+        ]
+
         def generate_lib_file(file_name, template_files):
             parts = []
             for template_file in template_files:
@@ -658,8 +666,10 @@
             outputs[file_name] = "\n\n".join(parts)
 
         generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Forward.h")), forward_h_templates)
-        generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.h")), lib_h_templates)
-        generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.cpp")), lib_cpp_templates)
+        generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.h")), protocol_h_templates)
+        generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "Protocol.cpp")), protocol_cpp_templates)
+        generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "base_string_adapter.h")), base_string_adapter_h_templates)
+        generate_lib_file(os.path.join(config.lib.output, to_file_name(config, "base_string_adapter.cc")), base_string_adapter_cc_templates)
 
     # Make gyp / make generatos happy, otherwise make rebuilds world.
     inputs_ts = max(map(os.path.getmtime, inputs))
diff --git a/third_party/inspector_protocol/encoding/cbor.cc b/third_party/inspector_protocol/encoding/cbor.cc
index 105ccf31..2f1efae 100644
--- a/third_party/inspector_protocol/encoding/cbor.cc
+++ b/third_party/inspector_protocol/encoding/cbor.cc
@@ -47,7 +47,13 @@
     EncodeInitialByte(MajorType::SIMPLE_VALUE, 22);
 static constexpr uint8_t kInitialByteForDouble =
     EncodeInitialByte(MajorType::SIMPLE_VALUE, 27);
+}  // namespace
 
+uint8_t EncodeTrue() { return kEncodedTrue; }
+uint8_t EncodeFalse() { return kEncodedFalse; }
+uint8_t EncodeNull() { return kEncodedNull; }
+
+namespace {
 // TAG 24 indicates that what follows is a byte string which is
 // encoded in CBOR format. We use this as a wrapper for
 // maps and arrays, allowing us to skip them, because the
@@ -71,7 +77,19 @@
 // length maps / arrays.
 static constexpr uint8_t kStopByte =
     EncodeInitialByte(MajorType::SIMPLE_VALUE, 31);
+}  // namespace
 
+uint8_t EncodeIndefiniteLengthArrayStart() {
+  return kInitialByteIndefiniteLengthArray;
+}
+
+uint8_t EncodeIndefiniteLengthMapStart() {
+  return kInitialByteIndefiniteLengthMap;
+}
+
+uint8_t EncodeStop() { return kStopByte; }
+
+namespace {
 // See RFC 7049 Table 3 and Section 2.4.4.2. This is used as a prefix for
 // arbitrary binary data encoded as BYTE_STRING.
 static constexpr uint8_t kExpectedConversionToBase64Tag =
@@ -116,7 +134,8 @@
   if (value <= std::numeric_limits<uint32_t>::max()) {
     // 32 bit uint: 1 initial byte + 4 bytes payload.
     encoded->push_back(EncodeInitialByte(type, kAdditionalInformation4Bytes));
-    WriteBytesMostSignificantByteFirst<uint32_t>(value, encoded);
+    WriteBytesMostSignificantByteFirst<uint32_t>(static_cast<uint32_t>(value),
+                                                 encoded);
     return;
   }
   // 64 bit uint: 1 initial byte + 8 bytes payload.
@@ -400,7 +419,7 @@
   if (tokenizer->TokenTag() == CBORTokenTag::ENVELOPE)
     tokenizer->EnterEnvelope();
   switch (tokenizer->TokenTag()) {
-    case CBORTokenTag::ERROR:
+    case CBORTokenTag::ERROR_VALUE:
       out->HandleError(tokenizer->Status());
       return false;
     case CBORTokenTag::DONE:
@@ -463,7 +482,7 @@
           Status{Error::CBOR_UNEXPECTED_EOF_IN_ARRAY, tokenizer->Status().pos});
       return false;
     }
-    if (tokenizer->TokenTag() == CBORTokenTag::ERROR) {
+    if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
       out->HandleError(tokenizer->Status());
       return false;
     }
@@ -489,7 +508,7 @@
           Status{Error::CBOR_UNEXPECTED_EOF_IN_MAP, tokenizer->Status().pos});
       return false;
     }
-    if (tokenizer->TokenTag() == CBORTokenTag::ERROR) {
+    if (tokenizer->TokenTag() == CBORTokenTag::ERROR_VALUE) {
       out->HandleError(tokenizer->Status());
       return false;
     }
@@ -522,7 +541,7 @@
     return;
   }
   CBORTokenizer tokenizer(bytes);
-  if (tokenizer.TokenTag() == CBORTokenTag::ERROR) {
+  if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
     json_out->HandleError(tokenizer.Status());
     return;
   }
@@ -537,7 +556,7 @@
   }
   if (!ParseMap(/*stack_depth=*/1, &tokenizer, json_out)) return;
   if (tokenizer.TokenTag() == CBORTokenTag::DONE) return;
-  if (tokenizer.TokenTag() == CBORTokenTag::ERROR) {
+  if (tokenizer.TokenTag() == CBORTokenTag::ERROR_VALUE) {
     json_out->HandleError(tokenizer.Status());
     return;
   }
@@ -553,7 +572,7 @@
 CBORTokenTag CBORTokenizer::TokenTag() const { return token_tag_; }
 
 void CBORTokenizer::Next() {
-  if (token_tag_ == CBORTokenTag::ERROR || token_tag_ == CBORTokenTag::DONE)
+  if (token_tag_ == CBORTokenTag::ERROR_VALUE || token_tag_ == CBORTokenTag::DONE)
     return;
   ReadNextToken(/*enter_envelope=*/false);
 }
@@ -568,9 +587,10 @@
 int32_t CBORTokenizer::GetInt32() const {
   assert(token_tag_ == CBORTokenTag::INT32);
   // The range checks happen in ::ReadNextToken().
-  return token_start_type_ == MajorType::UNSIGNED
-             ? token_start_internal_value_
-             : -static_cast<int64_t>(token_start_internal_value_) - 1;
+  return static_cast<uint32_t>(
+      token_start_type_ == MajorType::UNSIGNED
+          ? token_start_internal_value_
+          : -static_cast<int64_t>(token_start_internal_value_) - 1);
 }
 
 double CBORTokenizer::GetDouble() const {
@@ -744,7 +764,7 @@
 }
 
 void CBORTokenizer::SetError(Error error) {
-  token_tag_ = CBORTokenTag::ERROR;
+  token_tag_ = CBORTokenTag::ERROR_VALUE;
   status_.error = error;
 }
 
diff --git a/third_party/inspector_protocol/encoding/cbor.h b/third_party/inspector_protocol/encoding/cbor.h
index bf92a59..e0cf395 100644
--- a/third_party/inspector_protocol/encoding/cbor.h
+++ b/third_party/inspector_protocol/encoding/cbor.h
@@ -56,6 +56,14 @@
 // with additional info = 27, followed by 8 bytes in big endian.
 void EncodeDouble(double value, std::vector<uint8_t>* out);
 
+// Some constants for CBOR tokens that only take a single byte on the wire.
+uint8_t EncodeTrue();
+uint8_t EncodeFalse();
+uint8_t EncodeNull();
+uint8_t EncodeIndefiniteLengthArrayStart();
+uint8_t EncodeIndefiniteLengthMapStart();
+uint8_t EncodeStop();
+
 // An envelope indicates the byte length of a wrapped item.
 // We use this for maps and array, which allows the decoder
 // to skip such (nested) values whole sale.
@@ -97,7 +105,7 @@
 enum class CBORTokenTag {
   // Encountered an error in the structure of the message. Consult
   // status() for details.
-  ERROR,
+  ERROR_VALUE,
   // Booleans and NULL.
   TRUE_VALUE,
   FALSE_VALUE,
@@ -140,7 +148,7 @@
   ~CBORTokenizer();
 
   // Identifies the current token that we're looking at,
-  // or ERROR (in which ase ::Status() has details)
+  // or ERROR_VALUE (in which ase ::Status() has details)
   // or DONE (if we're past the last token).
   CBORTokenTag TokenTag() const;
 
@@ -152,10 +160,10 @@
   // letting the client explore the nested structure.
   void EnterEnvelope();
 
-  // If TokenTag() is CBORTokenTag::ERROR, then Status().error describes
+  // If TokenTag() is CBORTokenTag::ERROR_VALUE, then Status().error describes
   // the error more precisely; otherwise it'll be set to Error::OK.
   // In either case, Status().pos is the current position.
-  inspector_protocol::Status Status() const;
+  struct Status Status() const;
 
   // The following methods retrieve the token values. They can only
   // be called if TokenTag() matches.
@@ -183,7 +191,7 @@
 
   span<uint8_t> bytes_;
   CBORTokenTag token_tag_;
-  inspector_protocol::Status status_;
+  struct Status status_;
   int64_t token_byte_length_;
   cbor_internals::MajorType token_start_type_;
   uint64_t token_start_internal_value_;
diff --git a/third_party/inspector_protocol/encoding/cbor_test.cc b/third_party/inspector_protocol/encoding/cbor_test.cc
index 1b928f1..a71daad 100644
--- a/third_party/inspector_protocol/encoding/cbor_test.cc
+++ b/third_party/inspector_protocol/encoding/cbor_test.cc
@@ -113,7 +113,7 @@
   // Now try to decode; we treat this as an invalid INT32.
   CBORTokenizer tokenizer(span<uint8_t>(&encoded[0], encoded.size()));
   // 0xdeadbeef is > std::numerical_limits<int32_t>::max().
-  EXPECT_EQ(CBORTokenTag::ERROR, tokenizer.TokenTag());
+  EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
   EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error);
 }
 
@@ -136,7 +136,7 @@
     span<uint8_t> encoded_bytes(&test.data[0], test.data.size());
     CBORTokenizer tokenizer(
         span<uint8_t>(&encoded_bytes[0], encoded_bytes.size()));
-    EXPECT_EQ(CBORTokenTag::ERROR, tokenizer.TokenTag());
+    EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
     EXPECT_EQ(Error::CBOR_INVALID_INT32, tokenizer.Status().error);
   }
 }
@@ -292,7 +292,7 @@
   for (const TestCase& test : tests) {
     SCOPED_TRACE(test.msg);
     CBORTokenizer tokenizer(span<uint8_t>(&test.data[0], test.data.size()));
-    EXPECT_EQ(CBORTokenTag::ERROR, tokenizer.TokenTag());
+    EXPECT_EQ(CBORTokenTag::ERROR_VALUE, tokenizer.TokenTag());
     EXPECT_EQ(Error::CBOR_INVALID_STRING16, tokenizer.Status().error);
   }
 }
diff --git a/third_party/inspector_protocol/inspector_protocol.gni b/third_party/inspector_protocol/inspector_protocol.gni
index af2f216..b4acdf0b 100644
--- a/third_party/inspector_protocol/inspector_protocol.gni
+++ b/third_party/inspector_protocol/inspector_protocol.gni
@@ -31,6 +31,8 @@
 
     inputs = [
       invoker.config_file,
+      "$inspector_protocol_dir/lib/base_string_adapter_cc.template",
+      "$inspector_protocol_dir/lib/base_string_adapter_h.template",
       "$inspector_protocol_dir/lib/Allocator_h.template",
       "$inspector_protocol_dir/lib/Array_h.template",
       "$inspector_protocol_dir/lib/DispatcherBase_cpp.template",
diff --git a/content/browser/devtools/protocol_string.cc b/third_party/inspector_protocol/lib/base_string_adapter_cc.template
similarity index 83%
rename from content/browser/devtools/protocol_string.cc
rename to third_party/inspector_protocol/lib/base_string_adapter_cc.template
index 0b92afa..5ce0f68 100644
--- a/content/browser/devtools/protocol_string.cc
+++ b/third_party/inspector_protocol/lib/base_string_adapter_cc.template
@@ -1,8 +1,11 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
+// This file is generated by DispatcherBase_cpp.template.
+
+// 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 "content/browser/devtools/protocol_string.h"
+#include {{format_include(config.protocol.package, "base_string_adapter")}}
+#include {{format_include(config.protocol.package, "Protocol")}}
 
 #include <utility>
 #include "base/base64.h"
@@ -11,10 +14,10 @@
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/values.h"
-#include "content/browser/devtools/protocol/protocol.h"
 
-namespace content {
-namespace protocol {
+{% for namespace in config.protocol.namespace %}
+namespace {{namespace}} {
+{% endfor %}
 
 std::unique_ptr<protocol::Value> toProtocolValue(
     const base::Value* value, int depth) {
@@ -73,34 +76,33 @@
   return nullptr;
 }
 
-std::unique_ptr<base::Value> toBaseValue(
-    protocol::Value* value, int depth) {
+std::unique_ptr<base::Value> toBaseValue(Value* value, int depth) {
   if (!value || !depth)
     return nullptr;
-  if (value->type() == protocol::Value::TypeNull)
+  if (value->type() == Value::TypeNull)
     return std::make_unique<base::Value>();
-  if (value->type() == protocol::Value::TypeBoolean) {
+  if (value->type() == Value::TypeBoolean) {
     bool inner;
     value->asBoolean(&inner);
     return base::WrapUnique(new base::Value(inner));
   }
-  if (value->type() == protocol::Value::TypeInteger) {
+  if (value->type() == Value::TypeInteger) {
     int inner;
     value->asInteger(&inner);
     return base::WrapUnique(new base::Value(inner));
   }
-  if (value->type() == protocol::Value::TypeDouble) {
+  if (value->type() == Value::TypeDouble) {
     double inner;
     value->asDouble(&inner);
     return base::WrapUnique(new base::Value(inner));
   }
-  if (value->type() == protocol::Value::TypeString) {
+  if (value->type() == Value::TypeString) {
     std::string inner;
     value->asString(&inner);
     return base::WrapUnique(new base::Value(inner));
   }
-  if (value->type() == protocol::Value::TypeArray) {
-    protocol::ListValue* list = protocol::ListValue::cast(value);
+  if (value->type() == Value::TypeArray) {
+    ListValue* list = ListValue::cast(value);
     std::unique_ptr<base::ListValue> result(new base::ListValue());
     for (size_t i = 0; i < list->size(); i++) {
       std::unique_ptr<base::Value> converted =
@@ -110,11 +112,11 @@
     }
     return std::move(result);
   }
-  if (value->type() == protocol::Value::TypeObject) {
-    protocol::DictionaryValue* dict = protocol::DictionaryValue::cast(value);
+  if (value->type() == Value::TypeObject) {
+    DictionaryValue* dict = DictionaryValue::cast(value);
     std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue());
     for (size_t i = 0; i < dict->size(); i++) {
-      protocol::DictionaryValue::Entry entry = dict->at(i);
+      DictionaryValue::Entry entry = dict->at(i);
       std::unique_ptr<base::Value> converted =
           toBaseValue(entry.second, depth - 1);
       if (converted)
@@ -126,7 +128,7 @@
 }
 
 // static
-std::unique_ptr<protocol::Value> StringUtil::parseJSON(
+std::unique_ptr<Value> StringUtil::parseJSON(
     const std::string& json) {
   std::unique_ptr<base::Value> value = base::JSONReader::Read(json);
   return toProtocolValue(value.get(), 1000);
@@ -204,5 +206,7 @@
 Binary Binary::fromString(std::string data) {
   return Binary(base::RefCountedString::TakeString(&data));
 }
-}  // namespace protocol
-}  // namespace content
+
+{% for namespace in config.protocol.namespace %}
+} // namespace {{namespace}}
+{% endfor %}
diff --git a/headless/lib/browser/protocol/protocol_string.h b/third_party/inspector_protocol/lib/base_string_adapter_h.template
similarity index 73%
rename from headless/lib/browser/protocol/protocol_string.h
rename to third_party/inspector_protocol/lib/base_string_adapter_h.template
index 3f0bf13..bf860b6 100644
--- a/headless/lib/browser/protocol/protocol_string.h
+++ b/third_party/inspector_protocol/lib/base_string_adapter_h.template
@@ -1,9 +1,11 @@
-// Copyright 2018 The Chromium Authors. All rights reserved.
+// This file is generated by Parser_h.template.
+
+// 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 HEADLESS_LIB_BROWSER_PROTOCOL_PROTOCOL_STRING_H_
-#define HEADLESS_LIB_BROWSER_PROTOCOL_PROTOCOL_STRING_H_
+#ifndef {{"_".join(config.protocol.namespace)}}_Parser_h
+#define {{"_".join(config.protocol.namespace)}}_Parser_h
 
 #include <memory>
 #include <string>
@@ -13,20 +15,23 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/strings/string_number_conversions.h"
-#include "headless/public/headless_export.h"
+{% if config.lib.export_header %}
+#include "{{config.lib.export_header}}"
+{% endif %}
 
 namespace base {
 class Value;
 }
 
-namespace headless {
-namespace protocol {
+{% for namespace in config.protocol.namespace %}
+namespace {{namespace}} {
+{% endfor %}
 
 class Value;
 
 using String = std::string;
 
-class HEADLESS_EXPORT StringBuilder {
+class {{config.lib.export_macro}} StringBuilder {
  public:
   StringBuilder();
   ~StringBuilder();
@@ -40,12 +45,12 @@
   std::string string_;
 };
 
-class HEADLESS_EXPORT StringUtil {
+class {{config.lib.export_macro}} StringUtil {
  public:
   static String substring(const String& s, unsigned pos, unsigned len) {
     return s.substr(pos, len);
   }
-  static String fromInteger(int number) { return base::IntToString(number); }
+  static String fromInteger(int number) { return base::NumberToString(number); }
   static String fromDouble(double number) {
     String s = base::NumberToString(number);
     if (!s.empty() && s[0] == '.')
@@ -81,12 +86,15 @@
   static String builderToString(StringBuilder& builder) {
     return builder.toString();
   }
+  static std::vector<uint8_t> utf8data(const String& str) {
+    return std::vector<uint8_t>(str.begin(), str.end());
+  }
 
   static std::unique_ptr<Value> parseJSON(const String&);
 };
 
 // A read-only sequence of uninterpreted bytes with reference-counted storage.
-class HEADLESS_EXPORT Binary {
+class {{config.lib.export_macro}} Binary {
  public:
   Binary(const Binary&);
   Binary();
@@ -94,8 +102,10 @@
 
   const uint8_t* data() const { return bytes_->front(); }
   size_t size() const { return bytes_->size(); }
+  scoped_refptr<base::RefCountedMemory> bytes() const { return bytes_; }
 
   String toBase64() const;
+
   static Binary fromBase64(const String& base64, bool* success);
   static Binary fromRefCounted(scoped_refptr<base::RefCountedMemory> memory);
   static Binary fromVector(std::vector<uint8_t> data);
@@ -109,7 +119,8 @@
 std::unique_ptr<Value> toProtocolValue(const base::Value* value, int depth);
 std::unique_ptr<base::Value> toBaseValue(Value* value, int depth);
 
-}  // namespace protocol
-}  // namespace headless
+{% for namespace in config.protocol.namespace %}
+} // namespace {{namespace}}
+{% endfor %}
 
-#endif  // HEADLESS_LIB_BROWSER_PROTOCOL_PROTOCOL_STRING_H_
+#endif // !defined({{"_".join(config.protocol.namespace)}}_Parser_h)
diff --git a/third_party/webxr_test_pages/README.chromium b/third_party/webxr_test_pages/README.chromium
index 2fe57d3..2bf0d4ff 100644
--- a/third_party/webxr_test_pages/README.chromium
+++ b/third_party/webxr_test_pages/README.chromium
@@ -38,3 +38,8 @@
 2. Serve files, for example by running
    `python -m SimpleHTTPServer <port number>` in
    src/third_party/webxr_test_pages/webxr-samples
+
+3. If you are having trouble with the python server such as it being unreliable
+   serving media like the gltf files, try using "npm serve".
+   To install: `sudo npm install -g serve`
+   To run: `serve .` in src/third_party/webxr_test_pages/webxr-samples
diff --git a/third_party/webxr_test_pages/webxr-samples/input-tracking.html b/third_party/webxr_test_pages/webxr-samples/input-tracking.html
index 8ba16da6..46cb3bff 100644
--- a/third_party/webxr_test_pages/webxr-samples/input-tracking.html
+++ b/third_party/webxr_test_pages/webxr-samples/input-tracking.html
@@ -59,6 +59,7 @@
       import {QueryArgs} from './js/cottontail/src/util/query-args.js';
       import {FallbackHelper} from './js/cottontail/src/util/fallback-helper.js';
       import {SkyboxNode} from './js/cottontail/src/nodes/skybox.js';
+      import {vec3} from './js/cottontail/src/math/gl-matrix.js';
 
       // If requested, initialize the WebXR polyfill
       if (QueryArgs.getBool('allowPolyfill', false)) {
@@ -184,10 +185,10 @@
             continue;
           }
 
-          if (inputPose.gripMatrix) {
+          if (inputPose.gripTransform && inputPose.gripTransform.matrix) {
             // If we have a grip matrix use it to render a mesh showing the
             // position of the controller.
-            scene.inputRenderer.addController(inputPose.gripMatrix);
+            scene.inputRenderer.addController(inputPose.gripTransform.matrix);
           }
 
           if (inputPose.targetRay) {
diff --git a/third_party/webxr_test_pages/webxr-samples/js/cottontail/src/scenes/scene.js b/third_party/webxr_test_pages/webxr-samples/js/cottontail/src/scenes/scene.js
index d5b2350..dd68a0d 100644
--- a/third_party/webxr_test_pages/webxr-samples/js/cottontail/src/scenes/scene.js
+++ b/third_party/webxr_test_pages/webxr-samples/js/cottontail/src/scenes/scene.js
@@ -100,8 +100,8 @@
       }
 
       // Any time that we have a grip matrix, we'll render a controller.
-      if (inputPose.gripMatrix) {
-        this.inputRenderer.addController(inputPose.gripMatrix);
+      if (inputPose.gripTransform && inputPose.gripTransform.matrix) {
+        this.inputRenderer.addController(inputPose.gripTransform.matrix);
       }
 
       if (inputPose.targetRay) {
diff --git a/third_party/webxr_test_pages/webxr-samples/positional-audio.html b/third_party/webxr_test_pages/webxr-samples/positional-audio.html
index 2912365..4a1e0ee 100644
--- a/third_party/webxr_test_pages/webxr-samples/positional-audio.html
+++ b/third_party/webxr_test_pages/webxr-samples/positional-audio.html
@@ -61,7 +61,8 @@
       import {QueryArgs} from './js/cottontail/src/util/query-args.js';
       import {FallbackHelper} from './js/cottontail/src/util/fallback-helper.js';
       import {UrlTexture} from './js/cottontail/src/core/texture.js';
-      import {mat4} from './js/cottontail/src/math/gl-matrix.js';
+      import {mat4, vec3} from './js/cottontail/src/math/gl-matrix.js';
+      import {ButtonNode} from './js/cottontail/src/nodes/button.js';
 
       // If requested, initialize the WebXR polyfill
       if (QueryArgs.getBool('allowPolyfill', false)) {
@@ -461,7 +462,7 @@
         scene.drawXRFrame(frame, pose);
 
         if (pose) {
-          resonance.setListenerFromMatrix({ elements: pose.poseModelMatrix });
+          resonance.setListenerFromMatrix({ elements: pose.transform.matrix });
         }
 
         scene.endFrame();
diff --git a/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-hit-test.html b/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-hit-test.html
index 010cd0e..28241ae 100644
--- a/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-hit-test.html
+++ b/third_party/webxr_test_pages/webxr-samples/proposals/phone-ar-hit-test.html
@@ -246,12 +246,12 @@
         // If requested, use the pose to cast a reticle into the scene using a
         // continuous hit test. For the moment we're just using the flower
         // as the "reticle".
-        if (useReticle.checked && pose && pose.poseModelMatrix) {
+        if (useReticle.checked && pose && pose.transform.matrix) {
           vec3.set(rayOrigin, 0, 0, 0);
-          vec3.transformMat4(rayOrigin, rayOrigin, pose.poseModelMatrix);
+          vec3.transformMat4(rayOrigin, rayOrigin, pose.transform.matrix);
 
           vec3.set(rayDirection, 0, 0, -1);
-          vec3.transformMat4(rayDirection, rayDirection, pose.poseModelMatrix);
+          vec3.transformMat4(rayDirection, rayDirection, pose.transform.matrix);
           vec3.sub(rayDirection, rayDirection, rayOrigin);
           vec3.normalize(rayDirection, rayDirection);
 
diff --git a/third_party/webxr_test_pages/webxr-samples/spectator-mode.html b/third_party/webxr_test_pages/webxr-samples/spectator-mode.html
index c3aed33..38ad602 100644
--- a/third_party/webxr_test_pages/webxr-samples/spectator-mode.html
+++ b/third_party/webxr_test_pages/webxr-samples/spectator-mode.html
@@ -282,7 +282,7 @@
           // for this draw.
           if (headset) {
             headset.visible = true;
-            headset.matrix = pose.poseModelMatrix;
+            headset.matrix = pose.transform.matrix;
           }
 
           // Draw the spectator view of the scene.
diff --git a/third_party/webxr_test_pages/webxr-samples/tests/pointer-painter.html b/third_party/webxr_test_pages/webxr-samples/tests/pointer-painter.html
index 1032801..3435a4ae 100644
--- a/third_party/webxr_test_pages/webxr-samples/tests/pointer-painter.html
+++ b/third_party/webxr_test_pages/webxr-samples/tests/pointer-painter.html
@@ -204,8 +204,8 @@
             continue;
           }
 
-          if (inputPose.gripMatrix) {
-            scene.inputRenderer.addController(inputPose.gripMatrix);
+          if (inputPose.gripTransform && inputPose.gripTransform.matrix) {
+            scene.inputRenderer.addController(inputPose.gripTransform.matrix);
           }
 
           if (inputPose.targetRay && selecting) {
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index dfca081..6e363bf 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -21580,6 +21580,7 @@
   <int value="39" label="OrientationLock"/>
   <int value="40" label="Presentation"/>
   <int value="41" label="Frobulate"/>
+  <int value="42" label="Serial"/>
 </enum>
 
 <enum name="FeedbackSource">
@@ -30850,6 +30851,7 @@
   <int value="-1691668194" label="enable-new-bookmark-apps"/>
   <int value="-1691281364" label="enable-notification-action-icons"/>
   <int value="-1686782572" label="ChromeHomeInactivitySheetExpansion:disabled"/>
+  <int value="-1684123448" label="disable-best-effort-tasks"/>
   <int value="-1682843294" label="DataReductionProxyDecidesTransform:enabled"/>
   <int value="-1677715989" label="UnifiedConsent:disabled"/>
   <int value="-1676256979"
diff --git a/ui/accessibility/accessibility_switches.cc b/ui/accessibility/accessibility_switches.cc
index 3db61d6..62b62db 100644
--- a/ui/accessibility/accessibility_switches.cc
+++ b/ui/accessibility/accessibility_switches.cc
@@ -5,6 +5,7 @@
 #include "ui/accessibility/accessibility_switches.h"
 
 #include "base/command_line.h"
+#include "build/build_config.h"
 
 namespace switches {
 
@@ -44,4 +45,15 @@
       ::switches::kEnableExperimentalAccessibilityLanguageDetection);
 }
 
+#if defined(OS_WIN)
+// Toggles between IAccessible and UI Automation platform API.
+const char kEnableExperimentalUIAutomation[] =
+    "enable-experimental-ui-automation";
+
+bool IsExperimentalAccessibilityPlatformUIAEnabled() {
+  return base::CommandLine::ForCurrentProcess()->HasSwitch(
+      ::switches::kEnableExperimentalUIAutomation);
+}
+#endif
+
 }  // namespace switches
diff --git a/ui/accessibility/accessibility_switches.h b/ui/accessibility/accessibility_switches.h
index b2276023..ab2f4eb 100644
--- a/ui/accessibility/accessibility_switches.h
+++ b/ui/accessibility/accessibility_switches.h
@@ -6,6 +6,7 @@
 #ifndef UI_ACCESSIBILITY_ACCESSIBILITY_SWITCHES_H_
 #define UI_ACCESSIBILITY_ACCESSIBILITY_SWITCHES_H_
 
+#include "build/build_config.h"
 #include "ui/accessibility/ax_export.h"
 
 namespace switches {
@@ -23,6 +24,14 @@
 
 // Returns true if experimental accessibility language detection is enabled.
 AX_EXPORT bool AreExperimentalAccessibilityLanguageDetectionEnabled();
+
+#if defined(OS_WIN)
+AX_EXPORT extern const char kEnableExperimentalUIAutomation[];
+
+// Returns true if experimental support for UIAutomation is enabled.
+AX_EXPORT bool IsExperimentalAccessibilityPlatformUIAEnabled();
+#endif
+
 }  // namespace switches
 
 #endif  // UI_ACCESSIBILITY_ACCESSIBILITY_SWITCHES_H_
diff --git a/ui/events/ozone/evdev/keyboard_util_evdev.h b/ui/events/ozone/evdev/keyboard_util_evdev.h
index 3460ff5..56bde0c 100644
--- a/ui/events/ozone/evdev/keyboard_util_evdev.h
+++ b/ui/events/ozone/evdev/keyboard_util_evdev.h
@@ -5,10 +5,12 @@
 #ifndef UI_EVENTS_OZONE_EVDEV_KEYBOARD_UTIL_EVDEV_H_
 #define UI_EVENTS_OZONE_EVDEV_KEYBOARD_UTIL_EVDEV_H_
 
+#include "ui/events/ozone/evdev/events_ozone_evdev_export.h"
+
 namespace ui {
 
-int NativeCodeToEvdevCode(int native_code);
-int EvdevCodeToNativeCode(int evdev_code);
+int EVENTS_OZONE_EVDEV_EXPORT NativeCodeToEvdevCode(int native_code);
+int EVENTS_OZONE_EVDEV_EXPORT EvdevCodeToNativeCode(int evdev_code);
 
 }  // namespace ui
 
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
index 4507e9d..19d0e00d 100644
--- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
+++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc
@@ -8,6 +8,7 @@
 #include <xkbcommon/xkbcommon-names.h>
 
 #include <algorithm>
+#include <utility>
 
 #include "base/bind.h"
 #include "base/location.h"
@@ -832,7 +833,7 @@
       DVLOG(3) << "XKB keyboard layout does not contain " << flags[i].xkb_name;
     } else {
       xkb_mod_mask_t flag = static_cast<xkb_mod_mask_t>(1) << index;
-      XkbFlagMapEntry e = {flags[i].ui_flag, flag};
+      XkbFlagMapEntry e = {flags[i].ui_flag, flag, index};
       xkb_flag_map_.push_back(e);
     }
   }
@@ -861,6 +862,23 @@
   return xkb_flags;
 }
 
+int XkbKeyboardLayoutEngine::GetModifierFlags(uint32_t depressed,
+                                              uint32_t latched,
+                                              uint32_t locked,
+                                              uint32_t group) const {
+  auto* state = xkb_state_.get();
+  xkb_state_update_mask(state, depressed, latched, locked, 0, 0, group);
+  auto component = static_cast<xkb_state_component>(XKB_STATE_MODS_DEPRESSED |
+                                                    XKB_STATE_MODS_LATCHED |
+                                                    XKB_STATE_MODS_LOCKED);
+  int ui_flags = 0;
+  for (const auto& entry : xkb_flag_map_) {
+    if (xkb_state_mod_index_is_active(state, entry.xkb_index, component))
+      ui_flags |= entry.ui_flag;
+  }
+  return ui_flags;
+}
+
 bool XkbKeyboardLayoutEngine::XkbLookup(xkb_keycode_t xkb_keycode,
                                         xkb_mod_mask_t xkb_flags,
                                         xkb_keysym_t* xkb_keysym,
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h
index df8a45f..8c934d0 100644
--- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h
+++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h
@@ -9,6 +9,7 @@
 #include <xkbcommon/xkbcommon.h>
 
 #include <memory>
+#include <string>
 #include <vector>
 
 #include "base/memory/free_deleter.h"
@@ -26,7 +27,7 @@
 class EVENTS_OZONE_LAYOUT_EXPORT XkbKeyboardLayoutEngine
     : public KeyboardLayoutEngine {
  public:
-  XkbKeyboardLayoutEngine(const XkbKeyCodeConverter& converter);
+  explicit XkbKeyboardLayoutEngine(const XkbKeyCodeConverter& converter);
   ~XkbKeyboardLayoutEngine() override;
 
   // KeyboardLayoutEngine:
@@ -45,6 +46,11 @@
               DomKey* dom_key,
               KeyboardCode* key_code) const override;
 
+  int GetModifierFlags(uint32_t depressed,
+                       uint32_t latched,
+                       uint32_t locked,
+                       uint32_t group) const;
+
   static void ParseLayoutName(const std::string& layout_name,
                               std::string* layout_id,
                               std::string* layout_variant);
@@ -54,6 +60,7 @@
   struct XkbFlagMapEntry {
     int ui_flag;
     xkb_mod_mask_t xkb_flag;
+    xkb_mod_index_t xkb_index;
   };
   std::vector<XkbFlagMapEntry> xkb_flag_map_;
 
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index 03599eb5..ad65294 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -1345,7 +1345,43 @@
     var hideHelp = DialogType.isModal(fileManager.dialogType);
     event.canExecute = !hideHelp;
     event.command.setHidden(hideHelp);
-    fileManager.document.getElementById('help-separator').hidden = hideHelp;
+  }
+});
+
+/**
+ * Opens the send feedback window with pre-populated content.
+ */
+CommandHandler.COMMANDS_['send-feedback'] = /** @type {Command} */ ({
+  /**
+   * @param {!Event} event Command event.
+   * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use.
+   */
+  execute: function(event, fileManager) {
+    let message = {
+      categoryTag: 'chromeos-files-app',
+      requestFeedback: true,
+      feedbackInfo: {
+        description: '',
+      },
+    };
+
+    const kFeedbackExtensionId = 'gfdkimpbcpahaombhbimeihdjnejgicl';
+    // On ChromiumOS the feedback extension is not installed, so we just log
+    // that filing feedback has failed.
+    chrome.runtime.sendMessage(kFeedbackExtensionId, message, (response) => {
+      if (chrome.runtime.lastError) {
+        console.log(
+            'Failed to send feedback: ' + chrome.runtime.lastError.message);
+      }
+    });
+  },
+  /**
+   * @param {!Event} event Command event.
+   * @param {!CommandHandlerDeps} fileManager CommandHandlerDeps to use.
+   */
+  canExecute: function(event, fileManager) {
+    // Launching the feedback tool is always possible.
+    event.canExecute = true;
   }
 });
 
diff --git a/ui/file_manager/file_manager/foreground/js/file_selection.js b/ui/file_manager/file_manager/foreground/js/file_selection.js
index f8dfb68..5c359a9 100644
--- a/ui/file_manager/file_manager/foreground/js/file_selection.js
+++ b/ui/file_manager/file_manager/foreground/js/file_selection.js
@@ -139,7 +139,6 @@
    * @param {!MetadataModel} metadataModel
    * @param {!VolumeManager} volumeManager
    * @param {!AllowedPaths} allowedPaths
-   * @struct
    */
   constructor(
       directoryModel, fileOperationManager, listContainer, metadataModel,
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_list_selection_model.js b/ui/file_manager/file_manager/foreground/js/ui/file_list_selection_model.js
index 2b44f70..8c57553 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_list_selection_model.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_list_selection_model.js
@@ -35,9 +35,9 @@
    */
   adjustToReordering(permutation) {
     // Look at the old state.
-    var oldSelectedItemsCount = this.selectedIndexes.length;
-    var oldLeadIndex = this.leadIndex;
-    var newSelectedItemsCount =
+    const oldSelectedItemsCount = this.selectedIndexes.length;
+    const oldLeadIndex = this.leadIndex;
+    const newSelectedItemsCount =
         this.selectedIndexes.filter(i => permutation[i] != -1).length;
     // Call the superclass function.
     super.adjustToReordering(permutation);
@@ -59,7 +59,7 @@
     // mode. When the number of selected item is one, the mode depends on the
     // last keyboard/mouse operation. In this case, the mode is controlled from
     // outside. See filelist.handlePointerDownUp and filelist.handleKeyDown.
-    var selectedIndexes = this.selectedIndexes;
+    const selectedIndexes = this.selectedIndexes;
     if (selectedIndexes.length === 0) {
       this.isCheckSelectMode_ = false;
     } else if (selectedIndexes.length >= 2) {
diff --git a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
index dc4da04c..63cc452 100644
--- a/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
+++ b/ui/file_manager/file_manager/foreground/js/ui/file_table_list.js
@@ -5,7 +5,7 @@
 /**
  * Namespace for utility functions.
  */
-var filelist = {};
+const filelist = {};
 
 /**
  * File table list.
@@ -21,7 +21,7 @@
  * Decorates TableList as FileTableList.
  * @param {!cr.ui.table.TableList} self A tabel list element.
  */
-FileTableList.decorate = function(self) {
+FileTableList.decorate = self => {
   self.__proto__ = FileTableList.prototype;
 };
 
@@ -48,12 +48,12 @@
   // Make sure that list item's selected attribute is updated just after the
   // mergeItems operation is done. This prevents checkmarks on selected items
   // from being animated unintentionally by redraw.
-  for (var i = beginIndex; i < endIndex; i++) {
-    var item = this.getListItemByIndex(i);
+  for (let i = beginIndex; i < endIndex; i++) {
+    const item = this.getListItemByIndex(i);
     if (!item) {
       continue;
     }
-    var isSelected = this.selectionModel.getIndexSelected(i);
+    const isSelected = this.selectionModel.getIndexSelected(i);
     if (item.selected != isSelected) {
       item.selected = isSelected;
     }
@@ -85,9 +85,9 @@
    * @type {boolean}
    */
   this.enableTouchMode_ = false;
-  util.isTouchModeEnabled().then(function(enabled) {
+  util.isTouchModeEnabled().then(enabled => {
     this.enableTouchMode_ = enabled;
-  }.bind(this));
+  });
 
   /**
    * @type {!FileTapHandler}
@@ -131,12 +131,12 @@
  * @param {!MetadataModel} metadataModel Cache to
  *     retrieve metadada.
  */
-filelist.decorateListItem = function(li, entry, metadataModel) {
+filelist.decorateListItem = (li, entry, metadataModel) => {
   li.classList.add(entry.isDirectory ? 'directory' : 'file');
   // The metadata may not yet be ready. In that case, the list item will be
   // updated when the metadata is ready via updateListItemsMetadata. For files
   // not on an external backend, externalProps is not available.
-  var externalProps = metadataModel.getCache([entry], [
+  const externalProps = metadataModel.getCache([entry], [
     'hosted', 'availableOffline', 'customIconUrl', 'shared', 'isMachineRoot',
     'isExternalMedia'
   ])[0];
@@ -178,8 +178,8 @@
  * @param {string=} opt_mimeType Optional mime type for the file.
  * @return {!HTMLDivElement} Created element.
  */
-filelist.renderFileTypeIcon = function(doc, entry, locationInfo, opt_mimeType) {
-  var icon = /** @type {!HTMLDivElement} */ (doc.createElement('div'));
+filelist.renderFileTypeIcon = (doc, entry, locationInfo, opt_mimeType) => {
+  const icon = /** @type {!HTMLDivElement} */ (doc.createElement('div'));
   icon.className = 'detail-icon';
   icon.setAttribute(
       'file-type-icon',
@@ -194,12 +194,12 @@
  * @param {EntryLocation} locationInfo
  * @return {!HTMLDivElement} The label.
  */
-filelist.renderFileNameLabel = function(doc, entry, locationInfo) {
+filelist.renderFileNameLabel = (doc, entry, locationInfo) => {
   // Filename need to be in a '.filename-label' container for correct
   // work of inplace renaming.
-  var box = /** @type {!HTMLDivElement} */ (doc.createElement('div'));
+  const box = /** @type {!HTMLDivElement} */ (doc.createElement('div'));
   box.className = 'filename-label';
-  var fileName = doc.createElement('span');
+  const fileName = doc.createElement('span');
   fileName.className = 'entry-name';
   fileName.textContent = util.getEntryLabel(locationInfo, entry);
   box.appendChild(fileName);
@@ -212,8 +212,7 @@
  * @param {cr.ui.ListItem} li List item.
  * @param {Object} externalProps Metadata.
  */
-filelist.updateListItemExternalProps = function(
-    li, externalProps, isTeamDriveRoot) {
+filelist.updateListItemExternalProps = (li, externalProps, isTeamDriveRoot) => {
   if (li.classList.contains('file')) {
     if (externalProps.availableOffline === false) {
       li.classList.add('dim-offline');
@@ -231,7 +230,7 @@
     }
   }
 
-  var iconDiv = li.querySelector('.detail-icon');
+  const iconDiv = li.querySelector('.detail-icon');
   if (!iconDiv) {
     return;
   }
@@ -263,7 +262,7 @@
  * @this {cr.ui.ListSelectionController}
  */
 filelist.handleTap = function(e, index, eventType) {
-  var sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */
+  const sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */
       (this.selectionModel);
   if (eventType == FileTapHandler.TapEvent.TWO_FINGER_TAP) {
     // Prepare to open the context menu in the same manner as the right click.
@@ -276,7 +275,7 @@
       // not produce mousedown/click events.
       sm.unselectAll();
     } else {
-      var indexSelected = sm.getIndexSelected(index);
+      const indexSelected = sm.getIndexSelected(index);
       if (!indexSelected) {
         // Prepare to open context menu of the new item by selecting only it.
         if (sm.getCheckSelectMode()) {
@@ -297,13 +296,13 @@
   if (index == -1) {
     return false;
   }
-  var isTap = eventType == FileTapHandler.TapEvent.TAP ||
+  const isTap = eventType == FileTapHandler.TapEvent.TAP ||
       eventType == FileTapHandler.TapEvent.LONG_TAP;
   // Revert to click handling for single tap on checkbox or tap during rename.
   // Single tap on the checkbox in the list view mode should toggle select.
   // Single tap on input for rename should focus on input.
-  var isCheckbox = e.target.classList.contains('detail-checkmark');
-  var isRename = e.target.localName == 'input';
+  const isCheckbox = e.target.classList.contains('detail-checkmark');
+  const isRename = e.target.localName == 'input';
   if (eventType == FileTapHandler.TapEvent.TAP && (isCheckbox || isRename)) {
     return false;
   }
@@ -361,17 +360,17 @@
  * @this {cr.ui.ListSelectionController}
  */
 filelist.handlePointerDownUp = function(e, index) {
-  var sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */
+  const sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */
            (this.selectionModel);
-  var anchorIndex = sm.anchorIndex;
-  var isDown = (e.type == 'mousedown');
+  const anchorIndex = sm.anchorIndex;
+  const isDown = (e.type == 'mousedown');
 
-  var isTargetCheckmark = e.target.classList.contains('detail-checkmark') ||
+  const isTargetCheckmark = e.target.classList.contains('detail-checkmark') ||
                           e.target.classList.contains('checkmark');
   // If multiple selection is allowed and the checkmark is clicked without
   // modifiers(Ctrl/Shift), the click should toggle the item's selection.
   // (i.e. same behavior as Ctrl+Click)
-  var isClickOnCheckmark = isTargetCheckmark && sm.multiple && index != -1 &&
+  const isClickOnCheckmark = isTargetCheckmark && sm.multiple && index != -1 &&
                            !e.shiftKey && !e.ctrlKey && e.button == 0;
 
   sm.beginChange();
@@ -414,10 +413,10 @@
       }
     } else {
       // Right click for a context menu needs to not clear the selection.
-      var isRightClick = e.button == 2;
+      const isRightClick = e.button == 2;
 
       // If the index is selected this is handled in mouseup.
-      var indexSelected = sm.getIndexSelected(index);
+      const indexSelected = sm.getIndexSelected(index);
       if ((indexSelected && !isDown || !indexSelected && isDown) &&
           !(indexSelected && isRightClick)) {
         // 2) When non-checkmark area is clicked in check-select mode, disable
@@ -450,14 +449,14 @@
  * @this {cr.ui.ListSelectionController}
  */
 filelist.handleKeyDown = function(e) {
-  var SPACE_KEY_CODE = 32;
-  var tagName = e.target.tagName;
+  const SPACE_KEY_CODE = 32;
+  const tagName = e.target.tagName;
 
   // If focus is in an input field of some kind, only handle navigation keys
   // that aren't likely to conflict with input interaction (e.g., text
   // editing, or changing the value of a checkbox or select).
   if (tagName == 'INPUT') {
-    var inputType = e.target.type;
+    const inputType = e.target.type;
     // Just protect space (for toggling) for checkbox and radio.
     if (inputType == 'checkbox' || inputType == 'radio') {
       if (e.keyCode == SPACE_KEY_CODE) {
@@ -473,11 +472,11 @@
     return;
   }
 
-  var sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */
+  const sm = /** @type {!FileListSelectionModel|!FileListSingleSelectionModel} */
            (this.selectionModel);
-  var newIndex = -1;
-  var leadIndex = sm.leadIndex;
-  var prevent = true;
+  let newIndex = -1;
+  const leadIndex = sm.leadIndex;
+  let prevent = true;
 
   // Ctrl/Meta+A
   if (sm.multiple && e.keyCode == 65 &&
@@ -498,7 +497,7 @@
   // Space
   if (e.keyCode == SPACE_KEY_CODE) {
     if (leadIndex != -1) {
-      var selected = sm.getIndexSelected(leadIndex);
+      const selected = sm.getIndexSelected(leadIndex);
       if (e.ctrlKey || !selected) {
         sm.setIndexSelected(leadIndex, !selected || !sm.multiple);
         return;
@@ -540,7 +539,7 @@
 
     sm.leadIndex = newIndex;
     if (e.shiftKey) {
-      var anchorIndex = sm.anchorIndex;
+      const anchorIndex = sm.anchorIndex;
       if (sm.multiple) {
         sm.unselectAll();
       }
@@ -574,8 +573,8 @@
  * Focus on the file list that contains the event target.
  * @param {!Event} event the touch event.
  */
-filelist.focusParentList = function(event) {
-  var element = event.target;
+filelist.focusParentList = event => {
+  let element = event.target;
   while (element && !(element instanceof cr.ui.List)) {
     element = element.parentElement;
   }
diff --git a/ui/file_manager/file_manager/main.html b/ui/file_manager/file_manager/main.html
index aa682e4..967ef24 100644
--- a/ui/file_manager/file_manager/main.html
+++ b/ui/file_manager/file_manager/main.html
@@ -143,6 +143,7 @@
       <command id="configure" label="$i18n{CONFIGURE_VOLUME_BUTTON_LABEL}">
 
       <command id="volume-help" label="$i18n{DRIVE_MENU_HELP}">
+      <command id="send-feedback" label="$i18n{SEND_FEEDBACK}">
       <command id="volume-storage">
       <command id="drive-buy-more-space"
                label="$i18n{DRIVE_BUY_MORE_SPACE}">
@@ -287,6 +288,8 @@
                     command="#drive-go-to-drive"></cr-menu-item>
       <cr-menu-item id="gear-menu-volume-help"
                     command="#volume-help"></cr-menu-item>
+      <cr-menu-item id="gear-menu-send-feedback"
+                    command="#send-feedback"></cr-menu-item>
       <hr id="volume-space-info-separator">
       <cr-menu-item id="gear-menu-newservice" command="#new-service"
           sub-menu="#add-new-services-menu"></cr-menu-item>
diff --git a/ui/file_manager/integration_tests/file_manager/gear_menu.js b/ui/file_manager/integration_tests/file_manager/gear_menu.js
index e38cc21..9e832fb 100644
--- a/ui/file_manager/integration_tests/file_manager/gear_menu.js
+++ b/ui/file_manager/integration_tests/file_manager/gear_menu.js
@@ -486,3 +486,31 @@
   await remoteCall.waitForElement(
       appId, '#gear-menu-newfolder:not([disabled]):not([hidden])');
 };
+
+/**
+ * Tests that Send feedback appears in the gear menu.
+ */
+testcase.showSendFeedbackAction = async function() {
+  const entrySet = [ENTRIES.newlyAdded];
+
+  // Open Files.App on Downloads.
+  const appId = await openNewWindow(RootPath.DOWNLOADS);
+  await remoteCall.waitForElement(appId, '#file-list');
+
+  // Wait for the gear menu button to appear.
+  await remoteCall.waitForElement(appId, '#gear-button');
+
+  // Click the gear menu button.
+  chrome.test.assertTrue(await remoteCall.callRemoteTestUtil(
+      'fakeMouseClick', appId, ['#gear-button']));
+
+  // Wait for the gear menu to appear.
+  await remoteCall.waitForElement(appId, '#gear-menu:not([hidden])');
+
+  // Check #send-feedback is shown and it's enabled.
+  await remoteCall.waitForElement(
+      appId,
+      '#gear-menu:not([hidden]) cr-menu-item' +
+          '[command=\'#send-feedback\']' +
+          ':not([disabled]):not([hidden])');
+};
diff --git a/ui/gl/egl_bindings_autogen_mock.h b/ui/gl/egl_bindings_autogen_mock.h
index 1d5010b..24ccde5 100644
--- a/ui/gl/egl_bindings_autogen_mock.h
+++ b/ui/gl/egl_bindings_autogen_mock.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 static EGLBoolean GL_BINDING_CALL Mock_eglBindAPI(EGLenum api);
 static EGLBoolean GL_BINDING_CALL Mock_eglBindTexImage(EGLDisplay dpy,
diff --git a/ui/gl/generate_bindings.py b/ui/gl/generate_bindings.py
index a3841e7f7..d7eced05 100755
--- a/ui/gl/generate_bindings.py
+++ b/ui/gl/generate_bindings.py
@@ -837,6 +837,11 @@
       'GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, '
       'GLsizei* length, GLint* params', },
 { 'return_type': 'void',
+  'versions': [{'name': 'glGetInternalformatSampleivNV',
+                'extensions': ['GL_NV_internalformat_sample_query']}],
+  'arguments': 'GLenum target, GLenum internalformat, GLsizei samples, '
+               'GLenum pname, GLsizei bufSize, GLint* params', },
+{ 'return_type': 'void',
   'versions': [{'name': 'glGetMultisamplefv',
                 'extensions': ['GL_ARB_texture_multisample']}],
   'arguments': 'GLenum pname, GLuint index, GLfloat* val', },
@@ -936,7 +941,8 @@
   'GLsizei propCount, const GLenum* props, GLsizei bufSize, '
   'GLsizei* length, GLint* params'},
 { 'return_type': 'GLint',
-  'names': ['glGetProgramResourceLocation'],
+  'versions': [{'name': 'glGetProgramResourceLocation',
+                'extensions': ['GL_ARB_program_interface_query']}],
   'arguments': 'GLuint program, GLenum programInterface, const char* name', },
 { 'return_type': 'void',
   'versions': [{'name': 'glGetProgramResourceName',
@@ -1055,7 +1061,8 @@
       'GLuint shader, GLenum pname, GLsizei bufSize, GLsizei* length, '
       'GLint* params', },
 { 'return_type': 'void',
-  'names': ['glGetShaderPrecisionFormat'],
+  'versions': [{'name': 'glGetShaderPrecisionFormat',
+                'extensions': ['GL_ARB_ES2_compatibility']}],
   'arguments': 'GLenum shadertype, GLenum precisiontype, '
                'GLint* range, GLint* precision', },
 { 'return_type': 'void',
@@ -2875,9 +2882,9 @@
   file.write(LICENSE_AND_HEADER +
 """
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 """)
 
@@ -2896,9 +2903,9 @@
   file.write(LICENSE_AND_HEADER +
 """
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 """)
 
@@ -3370,9 +3377,9 @@
   file.write(LICENSE_AND_HEADER +
 """
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 """)
   uniquely_named_functions = GetUniquelyNamedFunctions(functions)
diff --git a/ui/gl/gl_bindings.h b/ui/gl/gl_bindings.h
index 3524f41..82213de 100644
--- a/ui/gl/gl_bindings.h
+++ b/ui/gl/gl_bindings.h
@@ -428,6 +428,13 @@
 #define GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM 0x8AF6
 #endif /* GL_CHROMIUM_shared_image */
 
+#ifndef GL_NV_internalformat_sample_query
+#define GL_MULTISAMPLES_NV 0x9371
+#define GL_SUPERSAMPLE_SCALE_X_NV 0x9372
+#define GL_SUPERSAMPLE_SCALE_Y_NV 0x9373
+#define GL_CONFORMANT_NV 0x9374
+#endif /* GL_NV_internalformat_sample_query */
+
 #define GL_GLEXT_PROTOTYPES 1
 
 #if defined(OS_WIN)
diff --git a/ui/gl/gl_bindings_api_autogen_egl.h b/ui/gl/gl_bindings_api_autogen_egl.h
index 7e3c0ef..7b033d0 100644
--- a/ui/gl/gl_bindings_api_autogen_egl.h
+++ b/ui/gl/gl_bindings_api_autogen_egl.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 EGLBoolean eglBindAPIFn(EGLenum api) override;
 EGLBoolean eglBindTexImageFn(EGLDisplay dpy,
diff --git a/ui/gl/gl_bindings_api_autogen_gl.h b/ui/gl/gl_bindings_api_autogen_gl.h
index 1595656..35d6e1a 100644
--- a/ui/gl/gl_bindings_api_autogen_gl.h
+++ b/ui/gl/gl_bindings_api_autogen_gl.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 void glActiveShaderProgramFn(GLuint pipeline, GLuint program) override;
 void glActiveTextureFn(GLenum texture) override;
@@ -540,6 +540,12 @@
                                         GLsizei bufSize,
                                         GLsizei* length,
                                         GLint* params) override;
+void glGetInternalformatSampleivNVFn(GLenum target,
+                                     GLenum internalformat,
+                                     GLsizei samples,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     GLint* params) override;
 void glGetMultisamplefvFn(GLenum pname, GLuint index, GLfloat* val) override;
 void glGetMultisamplefvRobustANGLEFn(GLenum pname,
                                      GLuint index,
diff --git a/ui/gl/gl_bindings_api_autogen_glx.h b/ui/gl/gl_bindings_api_autogen_glx.h
index 4ac732b..20a78ef 100644
--- a/ui/gl/gl_bindings_api_autogen_glx.h
+++ b/ui/gl/gl_bindings_api_autogen_glx.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 void glXBindTexImageEXTFn(Display* dpy,
                           GLXDrawable drawable,
diff --git a/ui/gl/gl_bindings_api_autogen_wgl.h b/ui/gl/gl_bindings_api_autogen_wgl.h
index 0b54c72..7df3023 100644
--- a/ui/gl/gl_bindings_api_autogen_wgl.h
+++ b/ui/gl/gl_bindings_api_autogen_wgl.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 BOOL wglChoosePixelFormatARBFn(HDC dc,
                                const int* int_attrib_list,
diff --git a/ui/gl/gl_bindings_autogen_gl.cc b/ui/gl/gl_bindings_autogen_gl.cc
index a8b45cfe..7c10353 100644
--- a/ui/gl/gl_bindings_autogen_gl.cc
+++ b/ui/gl/gl_bindings_autogen_gl.cc
@@ -298,14 +298,14 @@
   ext.b_GL_APPLE_fence = gfx::HasExtension(extensions, "GL_APPLE_fence");
   ext.b_GL_APPLE_vertex_array_object =
       gfx::HasExtension(extensions, "GL_APPLE_vertex_array_object");
+  ext.b_GL_ARB_ES2_compatibility =
+      gfx::HasExtension(extensions, "GL_ARB_ES2_compatibility");
   ext.b_GL_ARB_blend_func_extended =
       gfx::HasExtension(extensions, "GL_ARB_blend_func_extended");
   ext.b_GL_ARB_draw_buffers =
       gfx::HasExtension(extensions, "GL_ARB_draw_buffers");
   ext.b_GL_ARB_draw_instanced =
       gfx::HasExtension(extensions, "GL_ARB_draw_instanced");
-  ext.b_GL_ARB_ES2_compatibility =
-      gfx::HasExtension(extensions, "GL_ARB_ES2_compatibility");
   ext.b_GL_ARB_framebuffer_object =
       gfx::HasExtension(extensions, "GL_ARB_framebuffer_object");
   ext.b_GL_ARB_get_program_binary =
@@ -408,6 +408,8 @@
   ext.b_GL_NV_fence = gfx::HasExtension(extensions, "GL_NV_fence");
   ext.b_GL_NV_framebuffer_mixed_samples =
       gfx::HasExtension(extensions, "GL_NV_framebuffer_mixed_samples");
+  ext.b_GL_NV_internalformat_sample_query =
+      gfx::HasExtension(extensions, "GL_NV_internalformat_sample_query");
   ext.b_GL_NV_path_rendering =
       gfx::HasExtension(extensions, "GL_NV_path_rendering");
   ext.b_GL_OES_EGL_image = gfx::HasExtension(extensions, "GL_OES_EGL_image");
@@ -1297,6 +1299,12 @@
             GetGLProcAddress("glGetInternalformativRobustANGLE"));
   }
 
+  if (ext.b_GL_NV_internalformat_sample_query) {
+    fn.glGetInternalformatSampleivNVFn =
+        reinterpret_cast<glGetInternalformatSampleivNVProc>(
+            GetGLProcAddress("glGetInternalformatSampleivNV"));
+  }
+
   if (ver->IsAtLeastGL(3u, 2u) || ver->IsAtLeastGLES(3u, 1u) ||
       ext.b_GL_ARB_texture_multisample) {
     fn.glGetMultisamplefvFn = reinterpret_cast<glGetMultisamplefvProc>(
@@ -3812,6 +3820,16 @@
                                                  bufSize, length, params);
 }
 
+void GLApiBase::glGetInternalformatSampleivNVFn(GLenum target,
+                                                GLenum internalformat,
+                                                GLsizei samples,
+                                                GLenum pname,
+                                                GLsizei bufSize,
+                                                GLint* params) {
+  driver_->fn.glGetInternalformatSampleivNVFn(target, internalformat, samples,
+                                              pname, bufSize, params);
+}
+
 void GLApiBase::glGetMultisamplefvFn(GLenum pname, GLuint index, GLfloat* val) {
   driver_->fn.glGetMultisamplefvFn(pname, index, val);
 }
@@ -7078,6 +7096,18 @@
                                               bufSize, length, params);
 }
 
+void TraceGLApi::glGetInternalformatSampleivNVFn(GLenum target,
+                                                 GLenum internalformat,
+                                                 GLsizei samples,
+                                                 GLenum pname,
+                                                 GLsizei bufSize,
+                                                 GLint* params) {
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu",
+                                "TraceGLAPI::glGetInternalformatSampleivNV")
+  gl_api_->glGetInternalformatSampleivNVFn(target, internalformat, samples,
+                                           pname, bufSize, params);
+}
+
 void TraceGLApi::glGetMultisamplefvFn(GLenum pname,
                                       GLuint index,
                                       GLfloat* val) {
@@ -11103,6 +11133,21 @@
                                               bufSize, length, params);
 }
 
+void DebugGLApi::glGetInternalformatSampleivNVFn(GLenum target,
+                                                 GLenum internalformat,
+                                                 GLsizei samples,
+                                                 GLenum pname,
+                                                 GLsizei bufSize,
+                                                 GLint* params) {
+  GL_SERVICE_LOG("glGetInternalformatSampleivNV"
+                 << "(" << GLEnums::GetStringEnum(target) << ", "
+                 << GLEnums::GetStringEnum(internalformat) << ", " << samples
+                 << ", " << GLEnums::GetStringEnum(pname) << ", " << bufSize
+                 << ", " << static_cast<const void*>(params) << ")");
+  gl_api_->glGetInternalformatSampleivNVFn(target, internalformat, samples,
+                                           pname, bufSize, params);
+}
+
 void DebugGLApi::glGetMultisamplefvFn(GLenum pname,
                                       GLuint index,
                                       GLfloat* val) {
@@ -15216,6 +15261,15 @@
   NoContextHelper("glGetInternalformativRobustANGLE");
 }
 
+void NoContextGLApi::glGetInternalformatSampleivNVFn(GLenum target,
+                                                     GLenum internalformat,
+                                                     GLsizei samples,
+                                                     GLenum pname,
+                                                     GLsizei bufSize,
+                                                     GLint* params) {
+  NoContextHelper("glGetInternalformatSampleivNV");
+}
+
 void NoContextGLApi::glGetMultisamplefvFn(GLenum pname,
                                           GLuint index,
                                           GLfloat* val) {
diff --git a/ui/gl/gl_bindings_autogen_gl.h b/ui/gl/gl_bindings_autogen_gl.h
index 3af0694..ae8ec77b7 100644
--- a/ui/gl/gl_bindings_autogen_gl.h
+++ b/ui/gl/gl_bindings_autogen_gl.h
@@ -628,6 +628,13 @@
     GLsizei bufSize,
     GLsizei* length,
     GLint* params);
+typedef void(GL_BINDING_CALL* glGetInternalformatSampleivNVProc)(
+    GLenum target,
+    GLenum internalformat,
+    GLsizei samples,
+    GLenum pname,
+    GLsizei bufSize,
+    GLint* params);
 typedef void(GL_BINDING_CALL* glGetMultisamplefvProc)(GLenum pname,
                                                       GLuint index,
                                                       GLfloat* val);
@@ -1780,10 +1787,10 @@
   bool b_GL_ANGLE_translated_shader_source;
   bool b_GL_APPLE_fence;
   bool b_GL_APPLE_vertex_array_object;
+  bool b_GL_ARB_ES2_compatibility;
   bool b_GL_ARB_blend_func_extended;
   bool b_GL_ARB_draw_buffers;
   bool b_GL_ARB_draw_instanced;
-  bool b_GL_ARB_ES2_compatibility;
   bool b_GL_ARB_framebuffer_object;
   bool b_GL_ARB_get_program_binary;
   bool b_GL_ARB_instanced_arrays;
@@ -1838,6 +1845,7 @@
   bool b_GL_NV_blend_equation_advanced;
   bool b_GL_NV_fence;
   bool b_GL_NV_framebuffer_mixed_samples;
+  bool b_GL_NV_internalformat_sample_query;
   bool b_GL_NV_path_rendering;
   bool b_GL_OES_EGL_image;
   bool b_GL_OES_get_program_binary;
@@ -2032,6 +2040,7 @@
   glGetIntegervRobustANGLEProc glGetIntegervRobustANGLEFn;
   glGetInternalformativProc glGetInternalformativFn;
   glGetInternalformativRobustANGLEProc glGetInternalformativRobustANGLEFn;
+  glGetInternalformatSampleivNVProc glGetInternalformatSampleivNVFn;
   glGetMultisamplefvProc glGetMultisamplefvFn;
   glGetMultisamplefvRobustANGLEProc glGetMultisamplefvRobustANGLEFn;
   glGetnUniformfvRobustANGLEProc glGetnUniformfvRobustANGLEFn;
@@ -2873,6 +2882,12 @@
                                                   GLsizei bufSize,
                                                   GLsizei* length,
                                                   GLint* params) = 0;
+  virtual void glGetInternalformatSampleivNVFn(GLenum target,
+                                               GLenum internalformat,
+                                               GLsizei samples,
+                                               GLenum pname,
+                                               GLsizei bufSize,
+                                               GLint* params) = 0;
   virtual void glGetMultisamplefvFn(GLenum pname,
                                     GLuint index,
                                     GLfloat* val) = 0;
@@ -4156,6 +4171,8 @@
   ::gl::g_current_gl_context->glGetInternalformativFn
 #define glGetInternalformativRobustANGLE \
   ::gl::g_current_gl_context->glGetInternalformativRobustANGLEFn
+#define glGetInternalformatSampleivNV \
+  ::gl::g_current_gl_context->glGetInternalformatSampleivNVFn
 #define glGetMultisamplefv ::gl::g_current_gl_context->glGetMultisamplefvFn
 #define glGetMultisamplefvRobustANGLE \
   ::gl::g_current_gl_context->glGetMultisamplefvRobustANGLEFn
diff --git a/ui/gl/gl_bindings_autogen_mock.cc b/ui/gl/gl_bindings_autogen_mock.cc
index 7bc4154..3f011b2 100644
--- a/ui/gl/gl_bindings_autogen_mock.cc
+++ b/ui/gl/gl_bindings_autogen_mock.cc
@@ -1867,6 +1867,18 @@
 }
 
 void GL_BINDING_CALL
+MockGLInterface::Mock_glGetInternalformatSampleivNV(GLenum target,
+                                                    GLenum internalformat,
+                                                    GLsizei samples,
+                                                    GLenum pname,
+                                                    GLsizei bufSize,
+                                                    GLint* params) {
+  MakeGlMockFunctionUnique("glGetInternalformatSampleivNV");
+  interface_->GetInternalformatSampleivNV(target, internalformat, samples,
+                                          pname, bufSize, params);
+}
+
+void GL_BINDING_CALL
 MockGLInterface::Mock_glGetInternalformativ(GLenum target,
                                             GLenum internalformat,
                                             GLenum pname,
@@ -5375,6 +5387,9 @@
   if (strcmp(name, "glGetIntegervRobustANGLE") == 0)
     return reinterpret_cast<GLFunctionPointerType>(
         Mock_glGetIntegervRobustANGLE);
+  if (strcmp(name, "glGetInternalformatSampleivNV") == 0)
+    return reinterpret_cast<GLFunctionPointerType>(
+        Mock_glGetInternalformatSampleivNV);
   if (strcmp(name, "glGetInternalformativ") == 0)
     return reinterpret_cast<GLFunctionPointerType>(Mock_glGetInternalformativ);
   if (strcmp(name, "glGetInternalformativRobustANGLE") == 0)
diff --git a/ui/gl/gl_bindings_autogen_mock.h b/ui/gl/gl_bindings_autogen_mock.h
index eaab468..1ebfffcf 100644
--- a/ui/gl/gl_bindings_autogen_mock.h
+++ b/ui/gl/gl_bindings_autogen_mock.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 static void GL_BINDING_CALL Mock_glActiveShaderProgram(GLuint pipeline,
                                                        GLuint program);
@@ -772,6 +772,13 @@
                                                           GLsizei bufSize,
                                                           GLsizei* length,
                                                           GLint* data);
+static void GL_BINDING_CALL
+Mock_glGetInternalformatSampleivNV(GLenum target,
+                                   GLenum internalformat,
+                                   GLsizei samples,
+                                   GLenum pname,
+                                   GLsizei bufSize,
+                                   GLint* params);
 static void GL_BINDING_CALL Mock_glGetInternalformativ(GLenum target,
                                                        GLenum internalformat,
                                                        GLenum pname,
diff --git a/ui/gl/gl_enums_implementation_autogen.h b/ui/gl/gl_enums_implementation_autogen.h
index f1321998..192be83 100644
--- a/ui/gl/gl_enums_implementation_autogen.h
+++ b/ui/gl/gl_enums_implementation_autogen.h
@@ -13,4846 +13,6460 @@
 
 static const GLEnums::EnumToString enum_to_string_table[] = {
     {
-        0x00, "GL_CLOSE_PATH_NV",
+        0x00,
+        "GL_CLOSE_PATH_NV",
     },
     {
-        0x0000, "GL_POINTS",
+        0x0000,
+        "GL_POINTS",
     },
     {
-        0x00000000, "GL_PERFQUERY_SINGLE_CONTEXT_INTEL",
+        0x00000000,
+        "GL_PERFQUERY_SINGLE_CONTEXT_INTEL",
     },
     {
-        0x00000001, "GL_SYNC_FLUSH_COMMANDS_BIT_APPLE",
+        0x00000001,
+        "GL_SYNC_FLUSH_COMMANDS_BIT_APPLE",
     },
     {
-        0x00000002, "GL_CONTEXT_FLAG_DEBUG_BIT_KHR",
+        0x00000002,
+        "GL_CONTEXT_FLAG_DEBUG_BIT_KHR",
     },
     {
-        0x00000004, "GL_GEOMETRY_SHADER_BIT_OES",
+        0x00000004,
+        "GL_GEOMETRY_SHADER_BIT_OES",
     },
     {
-        0x00000008, "GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR",
+        0x00000008,
+        "GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR",
     },
     {
-        0x00000010, "GL_TESS_EVALUATION_SHADER_BIT_OES",
+        0x00000010,
+        "GL_TESS_EVALUATION_SHADER_BIT_OES",
     },
     {
-        0x00000020, "GL_COLOR_BUFFER_BIT5_QCOM",
+        0x00000020,
+        "GL_COLOR_BUFFER_BIT5_QCOM",
     },
     {
-        0x00000040, "GL_COLOR_BUFFER_BIT6_QCOM",
+        0x00000040,
+        "GL_COLOR_BUFFER_BIT6_QCOM",
     },
     {
-        0x00000080, "GL_COLOR_BUFFER_BIT7_QCOM",
+        0x00000080,
+        "GL_COLOR_BUFFER_BIT7_QCOM",
     },
     {
-        0x00000100, "GL_DEPTH_BUFFER_BIT",
+        0x00000100,
+        "GL_DEPTH_BUFFER_BIT",
     },
     {
-        0x00000200, "GL_DEPTH_BUFFER_BIT1_QCOM",
+        0x00000200,
+        "GL_DEPTH_BUFFER_BIT1_QCOM",
     },
     {
-        0x00000400, "GL_STENCIL_BUFFER_BIT",
+        0x00000400,
+        "GL_STENCIL_BUFFER_BIT",
     },
     {
-        0x00000800, "GL_DEPTH_BUFFER_BIT3_QCOM",
+        0x00000800,
+        "GL_DEPTH_BUFFER_BIT3_QCOM",
     },
     {
-        0x00001000, "GL_DEPTH_BUFFER_BIT4_QCOM",
+        0x00001000,
+        "GL_DEPTH_BUFFER_BIT4_QCOM",
     },
     {
-        0x00002000, "GL_DEPTH_BUFFER_BIT5_QCOM",
+        0x00002000,
+        "GL_DEPTH_BUFFER_BIT5_QCOM",
     },
     {
-        0x00004000, "GL_COLOR_BUFFER_BIT",
+        0x00004000,
+        "GL_COLOR_BUFFER_BIT",
     },
     {
-        0x00008000, "GL_COVERAGE_BUFFER_BIT_NV",
+        0x00008000,
+        "GL_COVERAGE_BUFFER_BIT_NV",
     },
     {
-        0x0001, "GL_LINES",
+        0x0001,
+        "GL_LINES",
     },
     {
-        0x00010000, "GL_FONT_X_MIN_BOUNDS_BIT_NV",
+        0x00010000,
+        "GL_FONT_X_MIN_BOUNDS_BIT_NV",
     },
     {
-        0x0002, "GL_LINE_LOOP",
+        0x0002,
+        "GL_LINE_LOOP",
     },
     {
-        0x00020000, "GL_FONT_Y_MIN_BOUNDS_BIT_NV",
+        0x00020000,
+        "GL_FONT_Y_MIN_BOUNDS_BIT_NV",
     },
     {
-        0x0003, "GL_LINE_STRIP",
+        0x0003,
+        "GL_LINE_STRIP",
     },
     {
-        0x0004, "GL_TRIANGLES",
+        0x0004,
+        "GL_TRIANGLES",
     },
     {
-        0x00040000, "GL_FONT_X_MAX_BOUNDS_BIT_NV",
+        0x00040000,
+        "GL_FONT_X_MAX_BOUNDS_BIT_NV",
     },
     {
-        0x0005, "GL_TRIANGLE_STRIP",
+        0x0005,
+        "GL_TRIANGLE_STRIP",
     },
     {
-        0x0006, "GL_TRIANGLE_FAN",
+        0x0006,
+        "GL_TRIANGLE_FAN",
     },
     {
-        0x0007, "GL_QUADS_OES",
+        0x0007,
+        "GL_QUADS_OES",
     },
     {
-        0x0008, "GL_MAP_INVALIDATE_BUFFER_BIT_EXT",
+        0x0008,
+        "GL_MAP_INVALIDATE_BUFFER_BIT_EXT",
     },
     {
-        0x00080000, "GL_FONT_Y_MAX_BOUNDS_BIT_NV",
+        0x00080000,
+        "GL_FONT_Y_MAX_BOUNDS_BIT_NV",
     },
     {
-        0x000A, "GL_LINES_ADJACENCY_OES",
+        0x000A,
+        "GL_LINES_ADJACENCY_OES",
     },
     {
-        0x000B, "GL_LINE_STRIP_ADJACENCY_OES",
+        0x000B,
+        "GL_LINE_STRIP_ADJACENCY_OES",
     },
     {
-        0x000C, "GL_TRIANGLES_ADJACENCY_OES",
+        0x000C,
+        "GL_TRIANGLES_ADJACENCY_OES",
     },
     {
-        0x000D, "GL_TRIANGLE_STRIP_ADJACENCY_OES",
+        0x000D,
+        "GL_TRIANGLE_STRIP_ADJACENCY_OES",
     },
     {
-        0x000E, "GL_PATCHES_OES",
+        0x000E,
+        "GL_PATCHES_OES",
     },
     {
-        0x0010, "GL_MAP_FLUSH_EXPLICIT_BIT_EXT",
+        0x0010,
+        "GL_MAP_FLUSH_EXPLICIT_BIT_EXT",
     },
     {
-        0x00100000, "GL_FONT_UNITS_PER_EM_BIT_NV",
+        0x00100000,
+        "GL_FONT_UNITS_PER_EM_BIT_NV",
     },
     {
-        0x0020, "GL_MAP_UNSYNCHRONIZED_BIT_EXT",
+        0x0020,
+        "GL_MAP_UNSYNCHRONIZED_BIT_EXT",
     },
     {
-        0x00200000, "GL_FONT_ASCENDER_BIT_NV",
+        0x00200000,
+        "GL_FONT_ASCENDER_BIT_NV",
     },
     {
-        0x0040, "GL_MAP_PERSISTENT_BIT_EXT",
+        0x0040,
+        "GL_MAP_PERSISTENT_BIT_EXT",
     },
     {
-        0x00400000, "GL_FONT_DESCENDER_BIT_NV",
+        0x00400000,
+        "GL_FONT_DESCENDER_BIT_NV",
     },
     {
-        0x0080, "GL_MAP_COHERENT_BIT_EXT",
+        0x0080,
+        "GL_MAP_COHERENT_BIT_EXT",
     },
     {
-        0x00800000, "GL_FONT_HEIGHT_BIT_NV",
+        0x00800000,
+        "GL_FONT_HEIGHT_BIT_NV",
     },
     {
-        0x01, "GL_BOLD_BIT_NV",
+        0x01,
+        "GL_BOLD_BIT_NV",
     },
     {
-        0x0100, "GL_DYNAMIC_STORAGE_BIT_EXT",
+        0x0100,
+        "GL_DYNAMIC_STORAGE_BIT_EXT",
     },
     {
-        0x01000000, "GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV",
+        0x01000000,
+        "GL_FONT_MAX_ADVANCE_WIDTH_BIT_NV",
     },
     {
-        0x02, "GL_MOVE_TO_NV",
+        0x02,
+        "GL_MOVE_TO_NV",
     },
     {
-        0x0200, "GL_NEVER",
+        0x0200,
+        "GL_NEVER",
     },
     {
-        0x02000000, "GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV",
+        0x02000000,
+        "GL_FONT_MAX_ADVANCE_HEIGHT_BIT_NV",
     },
     {
-        0x0201, "GL_LESS",
+        0x0201,
+        "GL_LESS",
     },
     {
-        0x0202, "GL_EQUAL",
+        0x0202,
+        "GL_EQUAL",
     },
     {
-        0x0203, "GL_LEQUAL",
+        0x0203,
+        "GL_LEQUAL",
     },
     {
-        0x0204, "GL_GREATER",
+        0x0204,
+        "GL_GREATER",
     },
     {
-        0x0205, "GL_NOTEQUAL",
+        0x0205,
+        "GL_NOTEQUAL",
     },
     {
-        0x0206, "GL_GEQUAL",
+        0x0206,
+        "GL_GEQUAL",
     },
     {
-        0x0207, "GL_ALWAYS",
+        0x0207,
+        "GL_ALWAYS",
     },
     {
-        0x03, "GL_RELATIVE_MOVE_TO_NV",
+        0x03,
+        "GL_RELATIVE_MOVE_TO_NV",
     },
     {
-        0x0300, "GL_SRC_COLOR",
+        0x0300,
+        "GL_SRC_COLOR",
     },
     {
-        0x0301, "GL_ONE_MINUS_SRC_COLOR",
+        0x0301,
+        "GL_ONE_MINUS_SRC_COLOR",
     },
     {
-        0x0302, "GL_SRC_ALPHA",
+        0x0302,
+        "GL_SRC_ALPHA",
     },
     {
-        0x0303, "GL_ONE_MINUS_SRC_ALPHA",
+        0x0303,
+        "GL_ONE_MINUS_SRC_ALPHA",
     },
     {
-        0x0304, "GL_DST_ALPHA",
+        0x0304,
+        "GL_DST_ALPHA",
     },
     {
-        0x0305, "GL_ONE_MINUS_DST_ALPHA",
+        0x0305,
+        "GL_ONE_MINUS_DST_ALPHA",
     },
     {
-        0x0306, "GL_DST_COLOR",
+        0x0306,
+        "GL_DST_COLOR",
     },
     {
-        0x0307, "GL_ONE_MINUS_DST_COLOR",
+        0x0307,
+        "GL_ONE_MINUS_DST_COLOR",
     },
     {
-        0x0308, "GL_SRC_ALPHA_SATURATE",
+        0x0308,
+        "GL_SRC_ALPHA_SATURATE",
     },
     {
-        0x04, "GL_LINE_TO_NV",
+        0x04,
+        "GL_LINE_TO_NV",
     },
     {
-        0x04000000, "GL_FONT_UNDERLINE_POSITION_BIT_NV",
+        0x04000000,
+        "GL_FONT_UNDERLINE_POSITION_BIT_NV",
     },
     {
-        0x0404, "GL_FRONT",
+        0x0404,
+        "GL_FRONT",
     },
     {
-        0x0405, "GL_BACK",
+        0x0405,
+        "GL_BACK",
     },
     {
-        0x0408, "GL_FRONT_AND_BACK",
+        0x0408,
+        "GL_FRONT_AND_BACK",
     },
     {
-        0x05, "GL_RELATIVE_LINE_TO_NV",
+        0x05,
+        "GL_RELATIVE_LINE_TO_NV",
     },
     {
-        0x0500, "GL_INVALID_ENUM",
+        0x0500,
+        "GL_INVALID_ENUM",
     },
     {
-        0x0501, "GL_INVALID_VALUE",
+        0x0501,
+        "GL_INVALID_VALUE",
     },
     {
-        0x0502, "GL_INVALID_OPERATION",
+        0x0502,
+        "GL_INVALID_OPERATION",
     },
     {
-        0x0503, "GL_STACK_OVERFLOW_KHR",
+        0x0503,
+        "GL_STACK_OVERFLOW_KHR",
     },
     {
-        0x0504, "GL_STACK_UNDERFLOW_KHR",
+        0x0504,
+        "GL_STACK_UNDERFLOW_KHR",
     },
     {
-        0x0505, "GL_OUT_OF_MEMORY",
+        0x0505,
+        "GL_OUT_OF_MEMORY",
     },
     {
-        0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION",
+        0x0506,
+        "GL_INVALID_FRAMEBUFFER_OPERATION",
     },
     {
-        0x0507, "GL_CONTEXT_LOST_KHR",
+        0x0507,
+        "GL_CONTEXT_LOST_KHR",
     },
     {
-        0x06, "GL_HORIZONTAL_LINE_TO_NV",
+        0x06,
+        "GL_HORIZONTAL_LINE_TO_NV",
     },
     {
-        0x07, "GL_RELATIVE_HORIZONTAL_LINE_TO_NV",
+        0x07,
+        "GL_RELATIVE_HORIZONTAL_LINE_TO_NV",
     },
     {
-        0x08, "GL_VERTICAL_LINE_TO_NV",
+        0x08,
+        "GL_VERTICAL_LINE_TO_NV",
     },
     {
-        0x08000000, "GL_FONT_UNDERLINE_THICKNESS_BIT_NV",
+        0x08000000,
+        "GL_FONT_UNDERLINE_THICKNESS_BIT_NV",
     },
     {
-        0x09, "GL_RELATIVE_VERTICAL_LINE_TO_NV",
+        0x09,
+        "GL_RELATIVE_VERTICAL_LINE_TO_NV",
     },
     {
-        0x0900, "GL_CW",
+        0x0900,
+        "GL_CW",
     },
     {
-        0x0901, "GL_CCW",
+        0x0901,
+        "GL_CCW",
     },
     {
-        0x0A, "GL_QUADRATIC_CURVE_TO_NV",
+        0x0A,
+        "GL_QUADRATIC_CURVE_TO_NV",
     },
     {
-        0x0B, "GL_RELATIVE_QUADRATIC_CURVE_TO_NV",
+        0x0B,
+        "GL_RELATIVE_QUADRATIC_CURVE_TO_NV",
     },
     {
-        0x0B21, "GL_LINE_WIDTH",
+        0x0B21,
+        "GL_LINE_WIDTH",
     },
     {
-        0x0B40, "GL_POLYGON_MODE_NV",
+        0x0B40,
+        "GL_POLYGON_MODE_NV",
     },
     {
-        0x0B44, "GL_CULL_FACE",
+        0x0B44,
+        "GL_CULL_FACE",
     },
     {
-        0x0B45, "GL_CULL_FACE_MODE",
+        0x0B45,
+        "GL_CULL_FACE_MODE",
     },
     {
-        0x0B46, "GL_FRONT_FACE",
+        0x0B46,
+        "GL_FRONT_FACE",
     },
     {
-        0x0B70, "GL_DEPTH_RANGE",
+        0x0B70,
+        "GL_DEPTH_RANGE",
     },
     {
-        0x0B71, "GL_DEPTH_TEST",
+        0x0B71,
+        "GL_DEPTH_TEST",
     },
     {
-        0x0B72, "GL_DEPTH_WRITEMASK",
+        0x0B72,
+        "GL_DEPTH_WRITEMASK",
     },
     {
-        0x0B73, "GL_DEPTH_CLEAR_VALUE",
+        0x0B73,
+        "GL_DEPTH_CLEAR_VALUE",
     },
     {
-        0x0B74, "GL_DEPTH_FUNC",
+        0x0B74,
+        "GL_DEPTH_FUNC",
     },
     {
-        0x0B90, "GL_STENCIL_TEST",
+        0x0B90,
+        "GL_STENCIL_TEST",
     },
     {
-        0x0B91, "GL_STENCIL_CLEAR_VALUE",
+        0x0B91,
+        "GL_STENCIL_CLEAR_VALUE",
     },
     {
-        0x0B92, "GL_STENCIL_FUNC",
+        0x0B92,
+        "GL_STENCIL_FUNC",
     },
     {
-        0x0B93, "GL_STENCIL_VALUE_MASK",
+        0x0B93,
+        "GL_STENCIL_VALUE_MASK",
     },
     {
-        0x0B94, "GL_STENCIL_FAIL",
+        0x0B94,
+        "GL_STENCIL_FAIL",
     },
     {
-        0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL",
+        0x0B95,
+        "GL_STENCIL_PASS_DEPTH_FAIL",
     },
     {
-        0x0B96, "GL_STENCIL_PASS_DEPTH_PASS",
+        0x0B96,
+        "GL_STENCIL_PASS_DEPTH_PASS",
     },
     {
-        0x0B97, "GL_STENCIL_REF",
+        0x0B97,
+        "GL_STENCIL_REF",
     },
     {
-        0x0B98, "GL_STENCIL_WRITEMASK",
+        0x0B98,
+        "GL_STENCIL_WRITEMASK",
     },
     {
-        0x0BA2, "GL_VIEWPORT",
+        0x0BA2,
+        "GL_VIEWPORT",
     },
     {
-        0x0BA3, "GL_PATH_MODELVIEW_STACK_DEPTH_NV",
+        0x0BA3,
+        "GL_PATH_MODELVIEW_STACK_DEPTH_NV",
     },
     {
-        0x0BA4, "GL_PATH_PROJECTION_STACK_DEPTH_NV",
+        0x0BA4,
+        "GL_PATH_PROJECTION_STACK_DEPTH_NV",
     },
     {
-        0x0BA6, "GL_PATH_MODELVIEW_MATRIX_NV",
+        0x0BA6,
+        "GL_PATH_MODELVIEW_MATRIX_NV",
     },
     {
-        0x0BA7, "GL_PATH_PROJECTION_MATRIX_NV",
+        0x0BA7,
+        "GL_PATH_PROJECTION_MATRIX_NV",
     },
     {
-        0x0BC0, "GL_ALPHA_TEST_QCOM",
+        0x0BC0,
+        "GL_ALPHA_TEST_QCOM",
     },
     {
-        0x0BC1, "GL_ALPHA_TEST_FUNC_QCOM",
+        0x0BC1,
+        "GL_ALPHA_TEST_FUNC_QCOM",
     },
     {
-        0x0BC2, "GL_ALPHA_TEST_REF_QCOM",
+        0x0BC2,
+        "GL_ALPHA_TEST_REF_QCOM",
     },
     {
-        0x0BD0, "GL_DITHER",
+        0x0BD0,
+        "GL_DITHER",
     },
     {
-        0x0BE2, "GL_BLEND",
+        0x0BE2,
+        "GL_BLEND",
     },
     {
-        0x0C, "GL_CUBIC_CURVE_TO_NV",
+        0x0C,
+        "GL_CUBIC_CURVE_TO_NV",
     },
     {
-        0x0C01, "GL_DRAW_BUFFER_EXT",
+        0x0C01,
+        "GL_DRAW_BUFFER_EXT",
     },
     {
-        0x0C02, "GL_READ_BUFFER_EXT",
+        0x0C02,
+        "GL_READ_BUFFER_EXT",
     },
     {
-        0x0C10, "GL_SCISSOR_BOX",
+        0x0C10,
+        "GL_SCISSOR_BOX",
     },
     {
-        0x0C11, "GL_SCISSOR_TEST",
+        0x0C11,
+        "GL_SCISSOR_TEST",
     },
     {
-        0x0C22, "GL_COLOR_CLEAR_VALUE",
+        0x0C22,
+        "GL_COLOR_CLEAR_VALUE",
     },
     {
-        0x0C23, "GL_COLOR_WRITEMASK",
+        0x0C23,
+        "GL_COLOR_WRITEMASK",
     },
     {
-        0x0CF2, "GL_UNPACK_ROW_LENGTH_EXT",
+        0x0CF2,
+        "GL_UNPACK_ROW_LENGTH_EXT",
     },
     {
-        0x0CF3, "GL_UNPACK_SKIP_ROWS_EXT",
+        0x0CF3,
+        "GL_UNPACK_SKIP_ROWS_EXT",
     },
     {
-        0x0CF4, "GL_UNPACK_SKIP_PIXELS_EXT",
+        0x0CF4,
+        "GL_UNPACK_SKIP_PIXELS_EXT",
     },
     {
-        0x0CF5, "GL_UNPACK_ALIGNMENT",
+        0x0CF5,
+        "GL_UNPACK_ALIGNMENT",
     },
     {
-        0x0D, "GL_RELATIVE_CUBIC_CURVE_TO_NV",
+        0x0D,
+        "GL_RELATIVE_CUBIC_CURVE_TO_NV",
     },
     {
-        0x0D02, "GL_PACK_ROW_LENGTH",
+        0x0D02,
+        "GL_PACK_ROW_LENGTH",
     },
     {
-        0x0D03, "GL_PACK_SKIP_ROWS",
+        0x0D03,
+        "GL_PACK_SKIP_ROWS",
     },
     {
-        0x0D04, "GL_PACK_SKIP_PIXELS",
+        0x0D04,
+        "GL_PACK_SKIP_PIXELS",
     },
     {
-        0x0D05, "GL_PACK_ALIGNMENT",
+        0x0D05,
+        "GL_PACK_ALIGNMENT",
     },
     {
-        0x0D32, "GL_MAX_CLIP_DISTANCES_APPLE",
+        0x0D32,
+        "GL_MAX_CLIP_DISTANCES_APPLE",
     },
     {
-        0x0D33, "GL_MAX_TEXTURE_SIZE",
+        0x0D33,
+        "GL_MAX_TEXTURE_SIZE",
     },
     {
-        0x0D36, "GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV",
+        0x0D36,
+        "GL_PATH_MAX_MODELVIEW_STACK_DEPTH_NV",
     },
     {
-        0x0D38, "GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV",
+        0x0D38,
+        "GL_PATH_MAX_PROJECTION_STACK_DEPTH_NV",
     },
     {
-        0x0D3A, "GL_MAX_VIEWPORT_DIMS",
+        0x0D3A,
+        "GL_MAX_VIEWPORT_DIMS",
     },
     {
-        0x0D50, "GL_SUBPIXEL_BITS",
+        0x0D50,
+        "GL_SUBPIXEL_BITS",
     },
     {
-        0x0D52, "GL_RED_BITS",
+        0x0D52,
+        "GL_RED_BITS",
     },
     {
-        0x0D53, "GL_GREEN_BITS",
+        0x0D53,
+        "GL_GREEN_BITS",
     },
     {
-        0x0D54, "GL_BLUE_BITS",
+        0x0D54,
+        "GL_BLUE_BITS",
     },
     {
-        0x0D55, "GL_ALPHA_BITS",
+        0x0D55,
+        "GL_ALPHA_BITS",
     },
     {
-        0x0D56, "GL_DEPTH_BITS",
+        0x0D56,
+        "GL_DEPTH_BITS",
     },
     {
-        0x0D57, "GL_STENCIL_BITS",
+        0x0D57,
+        "GL_STENCIL_BITS",
     },
     {
-        0x0DE1, "GL_TEXTURE_2D",
+        0x0DE1,
+        "GL_TEXTURE_2D",
     },
     {
-        0x0E, "GL_SMOOTH_QUADRATIC_CURVE_TO_NV",
+        0x0E,
+        "GL_SMOOTH_QUADRATIC_CURVE_TO_NV",
     },
     {
-        0x0F, "GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV",
+        0x0F,
+        "GL_RELATIVE_SMOOTH_QUADRATIC_CURVE_TO_NV",
     },
     {
-        0x1, "GL_CA_LAYER_EDGE_LEFT_CHROMIUM",
+        0x1,
+        "GL_CA_LAYER_EDGE_LEFT_CHROMIUM",
     },
     {
-        0x10, "GL_SMOOTH_CUBIC_CURVE_TO_NV",
+        0x10,
+        "GL_SMOOTH_CUBIC_CURVE_TO_NV",
     },
     {
-        0x100, "GL_GLYPH_HAS_KERNING_BIT_NV",
+        0x100,
+        "GL_GLYPH_HAS_KERNING_BIT_NV",
     },
     {
-        0x1000, "GL_TEXTURE_WIDTH",
+        0x1000,
+        "GL_TEXTURE_WIDTH",
     },
     {
-        0x10000000, "GL_FONT_HAS_KERNING_BIT_NV",
+        0x10000000,
+        "GL_FONT_HAS_KERNING_BIT_NV",
     },
     {
-        0x1001, "GL_TEXTURE_HEIGHT",
+        0x1001,
+        "GL_TEXTURE_HEIGHT",
     },
     {
-        0x1003, "GL_TEXTURE_INTERNAL_FORMAT",
+        0x1003,
+        "GL_TEXTURE_INTERNAL_FORMAT",
     },
     {
-        0x1004, "GL_TEXTURE_BORDER_COLOR_OES",
+        0x1004,
+        "GL_TEXTURE_BORDER_COLOR_OES",
     },
     {
-        0x11, "GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV",
+        0x11,
+        "GL_RELATIVE_SMOOTH_CUBIC_CURVE_TO_NV",
     },
     {
-        0x1100, "GL_DONT_CARE",
+        0x1100,
+        "GL_DONT_CARE",
     },
     {
-        0x1101, "GL_FASTEST",
+        0x1101,
+        "GL_FASTEST",
     },
     {
-        0x1102, "GL_NICEST",
+        0x1102,
+        "GL_NICEST",
     },
     {
-        0x12, "GL_SMALL_CCW_ARC_TO_NV",
+        0x12,
+        "GL_SMALL_CCW_ARC_TO_NV",
     },
     {
-        0x13, "GL_RELATIVE_SMALL_CCW_ARC_TO_NV",
+        0x13,
+        "GL_RELATIVE_SMALL_CCW_ARC_TO_NV",
     },
     {
-        0x14, "GL_SMALL_CW_ARC_TO_NV",
+        0x14,
+        "GL_SMALL_CW_ARC_TO_NV",
     },
     {
-        0x1400, "GL_BYTE",
+        0x1400,
+        "GL_BYTE",
     },
     {
-        0x1401, "GL_UNSIGNED_BYTE",
+        0x1401,
+        "GL_UNSIGNED_BYTE",
     },
     {
-        0x1402, "GL_SHORT",
+        0x1402,
+        "GL_SHORT",
     },
     {
-        0x1403, "GL_UNSIGNED_SHORT",
+        0x1403,
+        "GL_UNSIGNED_SHORT",
     },
     {
-        0x1404, "GL_INT",
+        0x1404,
+        "GL_INT",
     },
     {
-        0x1405, "GL_UNSIGNED_INT",
+        0x1405,
+        "GL_UNSIGNED_INT",
     },
     {
-        0x1406, "GL_FLOAT",
+        0x1406,
+        "GL_FLOAT",
     },
     {
-        0x140B, "GL_HALF_FLOAT",
+        0x140B,
+        "GL_HALF_FLOAT",
     },
     {
-        0x140C, "GL_FIXED",
+        0x140C,
+        "GL_FIXED",
     },
     {
-        0x140E, "GL_INT64_NV",
+        0x140E,
+        "GL_INT64_NV",
     },
     {
-        0x140F, "GL_UNSIGNED_INT64_NV",
+        0x140F,
+        "GL_UNSIGNED_INT64_NV",
     },
     {
-        0x15, "GL_RELATIVE_SMALL_CW_ARC_TO_NV",
+        0x15,
+        "GL_RELATIVE_SMALL_CW_ARC_TO_NV",
     },
     {
-        0x1506, "GL_XOR_NV",
+        0x1506,
+        "GL_XOR_NV",
     },
     {
-        0x150A, "GL_INVERT",
+        0x150A,
+        "GL_INVERT",
     },
     {
-        0x16, "GL_LARGE_CCW_ARC_TO_NV",
+        0x16,
+        "GL_LARGE_CCW_ARC_TO_NV",
     },
     {
-        0x17, "GL_RELATIVE_LARGE_CCW_ARC_TO_NV",
+        0x17,
+        "GL_RELATIVE_LARGE_CCW_ARC_TO_NV",
     },
     {
-        0x1700, "GL_PATH_MODELVIEW_NV",
+        0x1700,
+        "GL_PATH_MODELVIEW_NV",
     },
     {
-        0x1701, "GL_PATH_PROJECTION_NV",
+        0x1701,
+        "GL_PATH_PROJECTION_NV",
     },
     {
-        0x1702, "GL_TEXTURE",
+        0x1702,
+        "GL_TEXTURE",
     },
     {
-        0x18, "GL_LARGE_CW_ARC_TO_NV",
+        0x18,
+        "GL_LARGE_CW_ARC_TO_NV",
     },
     {
-        0x1800, "GL_COLOR_EXT",
+        0x1800,
+        "GL_COLOR_EXT",
     },
     {
-        0x1801, "GL_DEPTH_EXT",
+        0x1801,
+        "GL_DEPTH_EXT",
     },
     {
-        0x1802, "GL_STENCIL_EXT",
+        0x1802,
+        "GL_STENCIL_EXT",
     },
     {
-        0x19, "GL_RELATIVE_LARGE_CW_ARC_TO_NV",
+        0x19,
+        "GL_RELATIVE_LARGE_CW_ARC_TO_NV",
     },
     {
-        0x1901, "GL_STENCIL_INDEX_OES",
+        0x1901,
+        "GL_STENCIL_INDEX_OES",
     },
     {
-        0x1902, "GL_DEPTH_COMPONENT",
+        0x1902,
+        "GL_DEPTH_COMPONENT",
     },
     {
-        0x1903, "GL_RED_EXT",
+        0x1903,
+        "GL_RED_EXT",
     },
     {
-        0x1904, "GL_GREEN_NV",
+        0x1904,
+        "GL_GREEN_NV",
     },
     {
-        0x1905, "GL_BLUE_NV",
+        0x1905,
+        "GL_BLUE_NV",
     },
     {
-        0x1906, "GL_ALPHA",
+        0x1906,
+        "GL_ALPHA",
     },
     {
-        0x1907, "GL_RGB",
+        0x1907,
+        "GL_RGB",
     },
     {
-        0x1908, "GL_RGBA",
+        0x1908,
+        "GL_RGBA",
     },
     {
-        0x1909, "GL_LUMINANCE",
+        0x1909,
+        "GL_LUMINANCE",
     },
     {
-        0x190A, "GL_LUMINANCE_ALPHA",
+        0x190A,
+        "GL_LUMINANCE_ALPHA",
     },
     {
-        0x1A, "GL_CONIC_CURVE_TO_NV",
+        0x1A,
+        "GL_CONIC_CURVE_TO_NV",
     },
     {
-        0x1B, "GL_RELATIVE_CONIC_CURVE_TO_NV",
+        0x1B,
+        "GL_RELATIVE_CONIC_CURVE_TO_NV",
     },
     {
-        0x1B00, "GL_POINT_NV",
+        0x1B00,
+        "GL_POINT_NV",
     },
     {
-        0x1B01, "GL_LINE_NV",
+        0x1B01,
+        "GL_LINE_NV",
     },
     {
-        0x1B02, "GL_FILL_NV",
+        0x1B02,
+        "GL_FILL_NV",
     },
     {
-        0x1D00, "GL_FLAT_CHROMIUM",
+        0x1D00,
+        "GL_FLAT_CHROMIUM",
     },
     {
-        0x1E00, "GL_KEEP",
+        0x1E00,
+        "GL_KEEP",
     },
     {
-        0x1E01, "GL_REPLACE",
+        0x1E01,
+        "GL_REPLACE",
     },
     {
-        0x1E02, "GL_INCR",
+        0x1E02,
+        "GL_INCR",
     },
     {
-        0x1E03, "GL_DECR",
+        0x1E03,
+        "GL_DECR",
     },
     {
-        0x1F00, "GL_VENDOR",
+        0x1F00,
+        "GL_VENDOR",
     },
     {
-        0x1F01, "GL_RENDERER",
+        0x1F01,
+        "GL_RENDERER",
     },
     {
-        0x1F02, "GL_VERSION",
+        0x1F02,
+        "GL_VERSION",
     },
     {
-        0x1F03, "GL_EXTENSIONS",
+        0x1F03,
+        "GL_EXTENSIONS",
     },
     {
-        0x2, "GL_CA_LAYER_EDGE_RIGHT_CHROMIUM",
+        0x2,
+        "GL_CA_LAYER_EDGE_RIGHT_CHROMIUM",
     },
     {
-        0x20, "GL_GLYPH_VERTICAL_BEARING_X_BIT_NV",
+        0x20,
+        "GL_GLYPH_VERTICAL_BEARING_X_BIT_NV",
     },
     {
-        0x20000000, "GL_FONT_NUM_GLYPH_INDICES_BIT_NV",
+        0x20000000,
+        "GL_FONT_NUM_GLYPH_INDICES_BIT_NV",
     },
     {
-        0x2400, "GL_EYE_LINEAR_CHROMIUM",
+        0x2400,
+        "GL_EYE_LINEAR_CHROMIUM",
     },
     {
-        0x2401, "GL_OBJECT_LINEAR_CHROMIUM",
+        0x2401,
+        "GL_OBJECT_LINEAR_CHROMIUM",
     },
     {
-        0x2600, "GL_NEAREST",
+        0x2600,
+        "GL_NEAREST",
     },
     {
-        0x2601, "GL_LINEAR",
+        0x2601,
+        "GL_LINEAR",
     },
     {
-        0x2700, "GL_NEAREST_MIPMAP_NEAREST",
+        0x2700,
+        "GL_NEAREST_MIPMAP_NEAREST",
     },
     {
-        0x2701, "GL_LINEAR_MIPMAP_NEAREST",
+        0x2701,
+        "GL_LINEAR_MIPMAP_NEAREST",
     },
     {
-        0x2702, "GL_NEAREST_MIPMAP_LINEAR",
+        0x2702,
+        "GL_NEAREST_MIPMAP_LINEAR",
     },
     {
-        0x2703, "GL_LINEAR_MIPMAP_LINEAR",
+        0x2703,
+        "GL_LINEAR_MIPMAP_LINEAR",
     },
     {
-        0x2800, "GL_TEXTURE_MAG_FILTER",
+        0x2800,
+        "GL_TEXTURE_MAG_FILTER",
     },
     {
-        0x2801, "GL_TEXTURE_MIN_FILTER",
+        0x2801,
+        "GL_TEXTURE_MIN_FILTER",
     },
     {
-        0x2802, "GL_TEXTURE_WRAP_S",
+        0x2802,
+        "GL_TEXTURE_WRAP_S",
     },
     {
-        0x2803, "GL_TEXTURE_WRAP_T",
+        0x2803,
+        "GL_TEXTURE_WRAP_T",
     },
     {
-        0x2901, "GL_REPEAT",
+        0x2901,
+        "GL_REPEAT",
     },
     {
-        0x2A00, "GL_POLYGON_OFFSET_UNITS",
+        0x2A00,
+        "GL_POLYGON_OFFSET_UNITS",
     },
     {
-        0x2A01, "GL_POLYGON_OFFSET_POINT_NV",
+        0x2A01,
+        "GL_POLYGON_OFFSET_POINT_NV",
     },
     {
-        0x2A02, "GL_POLYGON_OFFSET_LINE_NV",
+        0x2A02,
+        "GL_POLYGON_OFFSET_LINE_NV",
     },
     {
-        0x3000, "GL_CLIP_DISTANCE0_APPLE",
+        0x3000,
+        "GL_CLIP_DISTANCE0_APPLE",
     },
     {
-        0x3001, "GL_CLIP_DISTANCE1_APPLE",
+        0x3001,
+        "GL_CLIP_DISTANCE1_APPLE",
     },
     {
-        0x3002, "GL_CLIP_DISTANCE2_APPLE",
+        0x3002,
+        "GL_CLIP_DISTANCE2_APPLE",
     },
     {
-        0x3003, "GL_CLIP_DISTANCE3_APPLE",
+        0x3003,
+        "GL_CLIP_DISTANCE3_APPLE",
     },
     {
-        0x3004, "GL_CLIP_DISTANCE4_APPLE",
+        0x3004,
+        "GL_CLIP_DISTANCE4_APPLE",
     },
     {
-        0x3005, "GL_CLIP_DISTANCE5_APPLE",
+        0x3005,
+        "GL_CLIP_DISTANCE5_APPLE",
     },
     {
-        0x3006, "GL_CLIP_DISTANCE6_APPLE",
+        0x3006,
+        "GL_CLIP_DISTANCE6_APPLE",
     },
     {
-        0x3007, "GL_CLIP_DISTANCE7_APPLE",
+        0x3007,
+        "GL_CLIP_DISTANCE7_APPLE",
     },
     {
-        0x300E, "GL_CONTEXT_LOST",
+        0x300E,
+        "GL_CONTEXT_LOST",
     },
     {
-        0x4, "GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM",
+        0x4,
+        "GL_CA_LAYER_EDGE_BOTTOM_CHROMIUM",
     },
     {
-        0x40, "GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV",
+        0x40,
+        "GL_GLYPH_VERTICAL_BEARING_Y_BIT_NV",
     },
     {
-        0x40000000, "GL_MULTISAMPLE_BUFFER_BIT6_QCOM",
+        0x40000000,
+        "GL_MULTISAMPLE_BUFFER_BIT6_QCOM",
     },
     {
-        0x6000, "GL_SCANOUT_CHROMIUM",
+        0x6000,
+        "GL_SCANOUT_CHROMIUM",
     },
     {
-        0x6003, "GL_GET_ERROR_QUERY_CHROMIUM",
+        0x6003,
+        "GL_GET_ERROR_QUERY_CHROMIUM",
     },
     {
-        0x6004, "GL_COMMANDS_ISSUED_CHROMIUM",
+        0x6004,
+        "GL_COMMANDS_ISSUED_CHROMIUM",
     },
     {
-        0x6006, "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM",
+        0x6006,
+        "GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM",
     },
     {
-        0x6007, "GL_LATENCY_QUERY_CHROMIUM",
+        0x6007,
+        "GL_LATENCY_QUERY_CHROMIUM",
     },
     {
-        0x78EC, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM",
+        0x78EC,
+        "GL_PIXEL_UNPACK_TRANSFER_BUFFER_CHROMIUM",
     },
     {
-        0x78ED, "GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM",
+        0x78ED,
+        "GL_PIXEL_PACK_TRANSFER_BUFFER_CHROMIUM",
     },
     {
-        0x78EE, "GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
+        0x78EE,
+        "GL_PIXEL_PACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
     },
     {
-        0x78EF, "GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
+        0x78EF,
+        "GL_PIXEL_UNPACK_TRANSFER_BUFFER_BINDING_CHROMIUM",
     },
     {
-        0x78FA, "GL_RGB_YCRCB_420_CHROMIUM",
+        0x78FA,
+        "GL_RGB_YCRCB_420_CHROMIUM",
     },
     {
-        0x78FB, "GL_RGB_YCBCR_422_CHROMIUM",
+        0x78FB,
+        "GL_RGB_YCBCR_422_CHROMIUM",
     },
     {
-        0x78FC, "GL_RGB_YCBCR_420V_CHROMIUM",
+        0x78FC,
+        "GL_RGB_YCBCR_420V_CHROMIUM",
     },
     {
-        0x8, "GL_CA_LAYER_EDGE_TOP_CHROMIUM",
+        0x8,
+        "GL_CA_LAYER_EDGE_TOP_CHROMIUM",
     },
     {
-        0x80, "GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV",
+        0x80,
+        "GL_GLYPH_VERTICAL_BEARING_ADVANCE_BIT_NV",
     },
     {
-        0x80000000, "GL_MULTISAMPLE_BUFFER_BIT7_QCOM",
+        0x80000000,
+        "GL_MULTISAMPLE_BUFFER_BIT7_QCOM",
     },
     {
-        0x8001, "GL_CONSTANT_COLOR",
+        0x8001,
+        "GL_CONSTANT_COLOR",
     },
     {
-        0x8002, "GL_ONE_MINUS_CONSTANT_COLOR",
+        0x8002,
+        "GL_ONE_MINUS_CONSTANT_COLOR",
     },
     {
-        0x8003, "GL_CONSTANT_ALPHA",
+        0x8003,
+        "GL_CONSTANT_ALPHA",
     },
     {
-        0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA",
+        0x8004,
+        "GL_ONE_MINUS_CONSTANT_ALPHA",
     },
     {
-        0x8005, "GL_BLEND_COLOR",
+        0x8005,
+        "GL_BLEND_COLOR",
     },
     {
-        0x8006, "GL_FUNC_ADD",
+        0x8006,
+        "GL_FUNC_ADD",
     },
     {
-        0x8007, "GL_MIN",
+        0x8007,
+        "GL_MIN",
     },
     {
-        0x8008, "GL_MAX",
+        0x8008,
+        "GL_MAX",
     },
     {
-        0x8009, "GL_BLEND_EQUATION",
+        0x8009,
+        "GL_BLEND_EQUATION",
     },
     {
-        0x800A, "GL_FUNC_SUBTRACT",
+        0x800A,
+        "GL_FUNC_SUBTRACT",
     },
     {
-        0x800B, "GL_FUNC_REVERSE_SUBTRACT",
+        0x800B,
+        "GL_FUNC_REVERSE_SUBTRACT",
     },
     {
-        0x8033, "GL_UNSIGNED_SHORT_4_4_4_4",
+        0x8033,
+        "GL_UNSIGNED_SHORT_4_4_4_4",
     },
     {
-        0x8034, "GL_UNSIGNED_SHORT_5_5_5_1",
+        0x8034,
+        "GL_UNSIGNED_SHORT_5_5_5_1",
     },
     {
-        0x8037, "GL_POLYGON_OFFSET_FILL",
+        0x8037,
+        "GL_POLYGON_OFFSET_FILL",
     },
     {
-        0x8038, "GL_POLYGON_OFFSET_FACTOR",
+        0x8038,
+        "GL_POLYGON_OFFSET_FACTOR",
     },
     {
-        0x803C, "GL_ALPHA8_OES",
+        0x803C,
+        "GL_ALPHA8_OES",
     },
     {
-        0x8040, "GL_LUMINANCE8_OES",
+        0x8040,
+        "GL_LUMINANCE8_OES",
     },
     {
-        0x8043, "GL_LUMINANCE4_ALPHA4_OES",
+        0x8043,
+        "GL_LUMINANCE4_ALPHA4_OES",
     },
     {
-        0x8045, "GL_LUMINANCE8_ALPHA8_OES",
+        0x8045,
+        "GL_LUMINANCE8_ALPHA8_OES",
     },
     {
-        0x8051, "GL_RGB8_OES",
+        0x8051,
+        "GL_RGB8_OES",
     },
     {
-        0x8052, "GL_RGB10_EXT",
+        0x8052,
+        "GL_RGB10_EXT",
     },
     {
-        0x8054, "GL_RGB16_EXT",
+        0x8054,
+        "GL_RGB16_EXT",
     },
     {
-        0x8056, "GL_RGBA4",
+        0x8056,
+        "GL_RGBA4",
     },
     {
-        0x8057, "GL_RGB5_A1",
+        0x8057,
+        "GL_RGB5_A1",
     },
     {
-        0x8058, "GL_RGBA8_OES",
+        0x8058,
+        "GL_RGBA8_OES",
     },
     {
-        0x8059, "GL_RGB10_A2_EXT",
+        0x8059,
+        "GL_RGB10_A2_EXT",
     },
     {
-        0x805B, "GL_RGBA16_EXT",
+        0x805B,
+        "GL_RGBA16_EXT",
     },
     {
-        0x805C, "GL_TEXTURE_RED_SIZE",
+        0x805C,
+        "GL_TEXTURE_RED_SIZE",
     },
     {
-        0x805D, "GL_TEXTURE_GREEN_SIZE",
+        0x805D,
+        "GL_TEXTURE_GREEN_SIZE",
     },
     {
-        0x805E, "GL_TEXTURE_BLUE_SIZE",
+        0x805E,
+        "GL_TEXTURE_BLUE_SIZE",
     },
     {
-        0x805F, "GL_TEXTURE_ALPHA_SIZE",
+        0x805F,
+        "GL_TEXTURE_ALPHA_SIZE",
     },
     {
-        0x8069, "GL_TEXTURE_BINDING_2D",
+        0x8069,
+        "GL_TEXTURE_BINDING_2D",
     },
     {
-        0x806A, "GL_TEXTURE_BINDING_3D_OES",
+        0x806A,
+        "GL_TEXTURE_BINDING_3D_OES",
     },
     {
-        0x806D, "GL_UNPACK_SKIP_IMAGES",
+        0x806D,
+        "GL_UNPACK_SKIP_IMAGES",
     },
     {
-        0x806E, "GL_UNPACK_IMAGE_HEIGHT",
+        0x806E,
+        "GL_UNPACK_IMAGE_HEIGHT",
     },
     {
-        0x806F, "GL_TEXTURE_3D_OES",
+        0x806F,
+        "GL_TEXTURE_3D_OES",
     },
     {
-        0x8071, "GL_TEXTURE_DEPTH",
+        0x8071,
+        "GL_TEXTURE_DEPTH",
     },
     {
-        0x8072, "GL_TEXTURE_WRAP_R_OES",
+        0x8072,
+        "GL_TEXTURE_WRAP_R_OES",
     },
     {
-        0x8073, "GL_MAX_3D_TEXTURE_SIZE_OES",
+        0x8073,
+        "GL_MAX_3D_TEXTURE_SIZE_OES",
     },
     {
-        0x8074, "GL_VERTEX_ARRAY_KHR",
+        0x8074,
+        "GL_VERTEX_ARRAY_KHR",
     },
     {
-        0x809D, "GL_MULTISAMPLE_EXT",
+        0x809D,
+        "GL_MULTISAMPLE_EXT",
     },
     {
-        0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE",
+        0x809E,
+        "GL_SAMPLE_ALPHA_TO_COVERAGE",
     },
     {
-        0x809F, "GL_SAMPLE_ALPHA_TO_ONE_EXT",
+        0x809F,
+        "GL_SAMPLE_ALPHA_TO_ONE_EXT",
     },
     {
-        0x80A0, "GL_SAMPLE_COVERAGE",
+        0x80A0,
+        "GL_SAMPLE_COVERAGE",
     },
     {
-        0x80A8, "GL_SAMPLE_BUFFERS",
+        0x80A8,
+        "GL_SAMPLE_BUFFERS",
     },
     {
-        0x80A9, "GL_SAMPLES",
+        0x80A9,
+        "GL_SAMPLES",
     },
     {
-        0x80AA, "GL_SAMPLE_COVERAGE_VALUE",
+        0x80AA,
+        "GL_SAMPLE_COVERAGE_VALUE",
     },
     {
-        0x80AB, "GL_SAMPLE_COVERAGE_INVERT",
+        0x80AB,
+        "GL_SAMPLE_COVERAGE_INVERT",
     },
     {
-        0x80C8, "GL_BLEND_DST_RGB",
+        0x80C8,
+        "GL_BLEND_DST_RGB",
     },
     {
-        0x80C9, "GL_BLEND_SRC_RGB",
+        0x80C9,
+        "GL_BLEND_SRC_RGB",
     },
     {
-        0x80CA, "GL_BLEND_DST_ALPHA",
+        0x80CA,
+        "GL_BLEND_DST_ALPHA",
     },
     {
-        0x80CB, "GL_BLEND_SRC_ALPHA",
+        0x80CB,
+        "GL_BLEND_SRC_ALPHA",
     },
     {
-        0x80E1, "GL_BGRA_EXT",
+        0x80E1,
+        "GL_BGRA_EXT",
     },
     {
-        0x80E8, "GL_MAX_ELEMENTS_VERTICES",
+        0x80E8,
+        "GL_MAX_ELEMENTS_VERTICES",
     },
     {
-        0x80E9, "GL_MAX_ELEMENTS_INDICES",
+        0x80E9,
+        "GL_MAX_ELEMENTS_INDICES",
     },
     {
-        0x812D, "GL_CLAMP_TO_BORDER_OES",
+        0x812D,
+        "GL_CLAMP_TO_BORDER_OES",
     },
     {
-        0x812F, "GL_CLAMP_TO_EDGE",
+        0x812F,
+        "GL_CLAMP_TO_EDGE",
     },
     {
-        0x813A, "GL_TEXTURE_MIN_LOD",
+        0x813A,
+        "GL_TEXTURE_MIN_LOD",
     },
     {
-        0x813B, "GL_TEXTURE_MAX_LOD",
+        0x813B,
+        "GL_TEXTURE_MAX_LOD",
     },
     {
-        0x813C, "GL_TEXTURE_BASE_LEVEL",
+        0x813C,
+        "GL_TEXTURE_BASE_LEVEL",
     },
     {
-        0x813D, "GL_TEXTURE_MAX_LEVEL_APPLE",
+        0x813D,
+        "GL_TEXTURE_MAX_LEVEL_APPLE",
     },
     {
-        0x8192, "GL_GENERATE_MIPMAP_HINT",
+        0x8192,
+        "GL_GENERATE_MIPMAP_HINT",
     },
     {
-        0x81A5, "GL_DEPTH_COMPONENT16",
+        0x81A5,
+        "GL_DEPTH_COMPONENT16",
     },
     {
-        0x81A6, "GL_DEPTH_COMPONENT24_OES",
+        0x81A6,
+        "GL_DEPTH_COMPONENT24_OES",
     },
     {
-        0x81A7, "GL_DEPTH_COMPONENT32_OES",
+        0x81A7,
+        "GL_DEPTH_COMPONENT32_OES",
     },
     {
-        0x8210, "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT",
+        0x8210,
+        "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT",
     },
     {
-        0x8211, "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT",
+        0x8211,
+        "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT",
     },
     {
-        0x8212, "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
+        0x8212,
+        "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE",
     },
     {
-        0x8213, "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
+        0x8213,
+        "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE",
     },
     {
-        0x8214, "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
+        0x8214,
+        "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE",
     },
     {
-        0x8215, "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
+        0x8215,
+        "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE",
     },
     {
-        0x8216, "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
+        0x8216,
+        "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE",
     },
     {
-        0x8217, "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
+        0x8217,
+        "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE",
     },
     {
-        0x8218, "GL_FRAMEBUFFER_DEFAULT",
+        0x8218,
+        "GL_FRAMEBUFFER_DEFAULT",
     },
     {
-        0x8219, "GL_FRAMEBUFFER_UNDEFINED_OES",
+        0x8219,
+        "GL_FRAMEBUFFER_UNDEFINED_OES",
     },
     {
-        0x821A, "GL_DEPTH_STENCIL_ATTACHMENT",
+        0x821A,
+        "GL_DEPTH_STENCIL_ATTACHMENT",
     },
     {
-        0x821B, "GL_MAJOR_VERSION",
+        0x821B,
+        "GL_MAJOR_VERSION",
     },
     {
-        0x821C, "GL_MINOR_VERSION",
+        0x821C,
+        "GL_MINOR_VERSION",
     },
     {
-        0x821D, "GL_NUM_EXTENSIONS",
+        0x821D,
+        "GL_NUM_EXTENSIONS",
     },
     {
-        0x821F, "GL_BUFFER_IMMUTABLE_STORAGE_EXT",
+        0x821F,
+        "GL_BUFFER_IMMUTABLE_STORAGE_EXT",
     },
     {
-        0x8220, "GL_BUFFER_STORAGE_FLAGS_EXT",
+        0x8220,
+        "GL_BUFFER_STORAGE_FLAGS_EXT",
     },
     {
-        0x8221, "GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES",
+        0x8221,
+        "GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED_OES",
     },
     {
-        0x8227, "GL_RG_EXT",
+        0x8227,
+        "GL_RG_EXT",
     },
     {
-        0x8228, "GL_RG_INTEGER",
+        0x8228,
+        "GL_RG_INTEGER",
     },
     {
-        0x8229, "GL_R8_EXT",
+        0x8229,
+        "GL_R8_EXT",
     },
     {
-        0x822A, "GL_R16_EXT",
+        0x822A,
+        "GL_R16_EXT",
     },
     {
-        0x822B, "GL_RG8_EXT",
+        0x822B,
+        "GL_RG8_EXT",
     },
     {
-        0x822C, "GL_RG16_EXT",
+        0x822C,
+        "GL_RG16_EXT",
     },
     {
-        0x822D, "GL_R16F_EXT",
+        0x822D,
+        "GL_R16F_EXT",
     },
     {
-        0x822E, "GL_R32F_EXT",
+        0x822E,
+        "GL_R32F_EXT",
     },
     {
-        0x822F, "GL_RG16F_EXT",
+        0x822F,
+        "GL_RG16F_EXT",
     },
     {
-        0x8230, "GL_RG32F_EXT",
+        0x8230,
+        "GL_RG32F_EXT",
     },
     {
-        0x8231, "GL_R8I",
+        0x8231,
+        "GL_R8I",
     },
     {
-        0x8232, "GL_R8UI",
+        0x8232,
+        "GL_R8UI",
     },
     {
-        0x8233, "GL_R16I",
+        0x8233,
+        "GL_R16I",
     },
     {
-        0x8234, "GL_R16UI",
+        0x8234,
+        "GL_R16UI",
     },
     {
-        0x8235, "GL_R32I",
+        0x8235,
+        "GL_R32I",
     },
     {
-        0x8236, "GL_R32UI",
+        0x8236,
+        "GL_R32UI",
     },
     {
-        0x8237, "GL_RG8I",
+        0x8237,
+        "GL_RG8I",
     },
     {
-        0x8238, "GL_RG8UI",
+        0x8238,
+        "GL_RG8UI",
     },
     {
-        0x8239, "GL_RG16I",
+        0x8239,
+        "GL_RG16I",
     },
     {
-        0x823A, "GL_RG16UI",
+        0x823A,
+        "GL_RG16UI",
     },
     {
-        0x823B, "GL_RG32I",
+        0x823B,
+        "GL_RG32I",
     },
     {
-        0x823C, "GL_RG32UI",
+        0x823C,
+        "GL_RG32UI",
     },
     {
-        0x8242, "GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR",
+        0x8242,
+        "GL_DEBUG_OUTPUT_SYNCHRONOUS_KHR",
     },
     {
-        0x8243, "GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR",
+        0x8243,
+        "GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_KHR",
     },
     {
-        0x8244, "GL_DEBUG_CALLBACK_FUNCTION_KHR",
+        0x8244,
+        "GL_DEBUG_CALLBACK_FUNCTION_KHR",
     },
     {
-        0x8245, "GL_DEBUG_CALLBACK_USER_PARAM_KHR",
+        0x8245,
+        "GL_DEBUG_CALLBACK_USER_PARAM_KHR",
     },
     {
-        0x8246, "GL_DEBUG_SOURCE_API_KHR",
+        0x8246,
+        "GL_DEBUG_SOURCE_API_KHR",
     },
     {
-        0x8247, "GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR",
+        0x8247,
+        "GL_DEBUG_SOURCE_WINDOW_SYSTEM_KHR",
     },
     {
-        0x8248, "GL_DEBUG_SOURCE_SHADER_COMPILER_KHR",
+        0x8248,
+        "GL_DEBUG_SOURCE_SHADER_COMPILER_KHR",
     },
     {
-        0x8249, "GL_DEBUG_SOURCE_THIRD_PARTY_KHR",
+        0x8249,
+        "GL_DEBUG_SOURCE_THIRD_PARTY_KHR",
     },
     {
-        0x824A, "GL_DEBUG_SOURCE_APPLICATION_KHR",
+        0x824A,
+        "GL_DEBUG_SOURCE_APPLICATION_KHR",
     },
     {
-        0x824B, "GL_DEBUG_SOURCE_OTHER_KHR",
+        0x824B,
+        "GL_DEBUG_SOURCE_OTHER_KHR",
     },
     {
-        0x824C, "GL_DEBUG_TYPE_ERROR_KHR",
+        0x824C,
+        "GL_DEBUG_TYPE_ERROR_KHR",
     },
     {
-        0x824D, "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR",
+        0x824D,
+        "GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_KHR",
     },
     {
-        0x824E, "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR",
+        0x824E,
+        "GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_KHR",
     },
     {
-        0x824F, "GL_DEBUG_TYPE_PORTABILITY_KHR",
+        0x824F,
+        "GL_DEBUG_TYPE_PORTABILITY_KHR",
     },
     {
-        0x8250, "GL_DEBUG_TYPE_PERFORMANCE_KHR",
+        0x8250,
+        "GL_DEBUG_TYPE_PERFORMANCE_KHR",
     },
     {
-        0x8251, "GL_DEBUG_TYPE_OTHER_KHR",
+        0x8251,
+        "GL_DEBUG_TYPE_OTHER_KHR",
     },
     {
-        0x8252, "GL_LOSE_CONTEXT_ON_RESET_KHR",
+        0x8252,
+        "GL_LOSE_CONTEXT_ON_RESET_KHR",
     },
     {
-        0x8253, "GL_GUILTY_CONTEXT_RESET_KHR",
+        0x8253,
+        "GL_GUILTY_CONTEXT_RESET_KHR",
     },
     {
-        0x8254, "GL_INNOCENT_CONTEXT_RESET_KHR",
+        0x8254,
+        "GL_INNOCENT_CONTEXT_RESET_KHR",
     },
     {
-        0x8255, "GL_UNKNOWN_CONTEXT_RESET_KHR",
+        0x8255,
+        "GL_UNKNOWN_CONTEXT_RESET_KHR",
     },
     {
-        0x8256, "GL_RESET_NOTIFICATION_STRATEGY_KHR",
+        0x8256,
+        "GL_RESET_NOTIFICATION_STRATEGY_KHR",
     },
     {
-        0x8257, "GL_PROGRAM_BINARY_RETRIEVABLE_HINT",
+        0x8257,
+        "GL_PROGRAM_BINARY_RETRIEVABLE_HINT",
     },
     {
-        0x8258, "GL_PROGRAM_SEPARABLE_EXT",
+        0x8258,
+        "GL_PROGRAM_SEPARABLE_EXT",
     },
     {
-        0x8259, "GL_ACTIVE_PROGRAM_EXT",
+        0x8259,
+        "GL_ACTIVE_PROGRAM_EXT",
     },
     {
-        0x825A, "GL_PROGRAM_PIPELINE_BINDING_EXT",
+        0x825A,
+        "GL_PROGRAM_PIPELINE_BINDING_EXT",
     },
     {
-        0x825B, "GL_MAX_VIEWPORTS_OES",
+        0x825B,
+        "GL_MAX_VIEWPORTS_OES",
     },
     {
-        0x825C, "GL_VIEWPORT_SUBPIXEL_BITS_OES",
+        0x825C,
+        "GL_VIEWPORT_SUBPIXEL_BITS_OES",
     },
     {
-        0x825D, "GL_VIEWPORT_BOUNDS_RANGE_OES",
+        0x825D,
+        "GL_VIEWPORT_BOUNDS_RANGE_OES",
     },
     {
-        0x825E, "GL_LAYER_PROVOKING_VERTEX_OES",
+        0x825E,
+        "GL_LAYER_PROVOKING_VERTEX_OES",
     },
     {
-        0x825F, "GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES",
+        0x825F,
+        "GL_VIEWPORT_INDEX_PROVOKING_VERTEX_OES",
     },
     {
-        0x8260, "GL_UNDEFINED_VERTEX_OES",
+        0x8260,
+        "GL_UNDEFINED_VERTEX_OES",
     },
     {
-        0x8261, "GL_NO_RESET_NOTIFICATION_KHR",
+        0x8261,
+        "GL_NO_RESET_NOTIFICATION_KHR",
     },
     {
-        0x8262, "GL_MAX_COMPUTE_SHARED_MEMORY_SIZE",
+        0x8262,
+        "GL_MAX_COMPUTE_SHARED_MEMORY_SIZE",
     },
     {
-        0x8263, "GL_MAX_COMPUTE_UNIFORM_COMPONENTS",
+        0x8263,
+        "GL_MAX_COMPUTE_UNIFORM_COMPONENTS",
     },
     {
-        0x8264, "GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS",
+        0x8264,
+        "GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS",
     },
     {
-        0x8265, "GL_MAX_COMPUTE_ATOMIC_COUNTERS",
+        0x8265,
+        "GL_MAX_COMPUTE_ATOMIC_COUNTERS",
     },
     {
-        0x8266, "GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS",
+        0x8266,
+        "GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS",
     },
     {
-        0x8267, "GL_COMPUTE_WORK_GROUP_SIZE",
+        0x8267,
+        "GL_COMPUTE_WORK_GROUP_SIZE",
     },
     {
-        0x8268, "GL_DEBUG_TYPE_MARKER_KHR",
+        0x8268,
+        "GL_DEBUG_TYPE_MARKER_KHR",
     },
     {
-        0x8269, "GL_DEBUG_TYPE_PUSH_GROUP_KHR",
+        0x8269,
+        "GL_DEBUG_TYPE_PUSH_GROUP_KHR",
     },
     {
-        0x826A, "GL_DEBUG_TYPE_POP_GROUP_KHR",
+        0x826A,
+        "GL_DEBUG_TYPE_POP_GROUP_KHR",
     },
     {
-        0x826B, "GL_DEBUG_SEVERITY_NOTIFICATION_KHR",
+        0x826B,
+        "GL_DEBUG_SEVERITY_NOTIFICATION_KHR",
     },
     {
-        0x826C, "GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR",
+        0x826C,
+        "GL_MAX_DEBUG_GROUP_STACK_DEPTH_KHR",
     },
     {
-        0x826D, "GL_DEBUG_GROUP_STACK_DEPTH_KHR",
+        0x826D,
+        "GL_DEBUG_GROUP_STACK_DEPTH_KHR",
     },
     {
-        0x826E, "GL_MAX_UNIFORM_LOCATIONS",
+        0x826E,
+        "GL_MAX_UNIFORM_LOCATIONS",
     },
     {
-        0x82D4, "GL_VERTEX_ATTRIB_BINDING",
+        0x82D4,
+        "GL_VERTEX_ATTRIB_BINDING",
     },
     {
-        0x82D5, "GL_VERTEX_ATTRIB_RELATIVE_OFFSET",
+        0x82D5,
+        "GL_VERTEX_ATTRIB_RELATIVE_OFFSET",
     },
     {
-        0x82D6, "GL_VERTEX_BINDING_DIVISOR",
+        0x82D6,
+        "GL_VERTEX_BINDING_DIVISOR",
     },
     {
-        0x82D7, "GL_VERTEX_BINDING_OFFSET",
+        0x82D7,
+        "GL_VERTEX_BINDING_OFFSET",
     },
     {
-        0x82D8, "GL_VERTEX_BINDING_STRIDE",
+        0x82D8,
+        "GL_VERTEX_BINDING_STRIDE",
     },
     {
-        0x82D9, "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET",
+        0x82D9,
+        "GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET",
     },
     {
-        0x82DA, "GL_MAX_VERTEX_ATTRIB_BINDINGS",
+        0x82DA,
+        "GL_MAX_VERTEX_ATTRIB_BINDINGS",
     },
     {
-        0x82DB, "GL_TEXTURE_VIEW_MIN_LEVEL_OES",
+        0x82DB,
+        "GL_TEXTURE_VIEW_MIN_LEVEL_OES",
     },
     {
-        0x82DC, "GL_TEXTURE_VIEW_NUM_LEVELS_OES",
+        0x82DC,
+        "GL_TEXTURE_VIEW_NUM_LEVELS_OES",
     },
     {
-        0x82DD, "GL_TEXTURE_VIEW_MIN_LAYER_OES",
+        0x82DD,
+        "GL_TEXTURE_VIEW_MIN_LAYER_OES",
     },
     {
-        0x82DE, "GL_TEXTURE_VIEW_NUM_LAYERS_OES",
+        0x82DE,
+        "GL_TEXTURE_VIEW_NUM_LAYERS_OES",
     },
     {
-        0x82DF, "GL_TEXTURE_IMMUTABLE_LEVELS",
+        0x82DF,
+        "GL_TEXTURE_IMMUTABLE_LEVELS",
     },
     {
-        0x82E0, "GL_BUFFER_KHR",
+        0x82E0,
+        "GL_BUFFER_KHR",
     },
     {
-        0x82E1, "GL_SHADER_KHR",
+        0x82E1,
+        "GL_SHADER_KHR",
     },
     {
-        0x82E2, "GL_PROGRAM_KHR",
+        0x82E2,
+        "GL_PROGRAM_KHR",
     },
     {
-        0x82E3, "GL_QUERY_KHR",
+        0x82E3,
+        "GL_QUERY_KHR",
     },
     {
-        0x82E4, "GL_PROGRAM_PIPELINE_KHR",
+        0x82E4,
+        "GL_PROGRAM_PIPELINE_KHR",
     },
     {
-        0x82E5, "GL_MAX_VERTEX_ATTRIB_STRIDE",
+        0x82E5,
+        "GL_MAX_VERTEX_ATTRIB_STRIDE",
     },
     {
-        0x82E6, "GL_SAMPLER_KHR",
+        0x82E6,
+        "GL_SAMPLER_KHR",
     },
     {
-        0x82E8, "GL_MAX_LABEL_LENGTH_KHR",
+        0x82E8,
+        "GL_MAX_LABEL_LENGTH_KHR",
     },
     {
-        0x82F9, "GL_MAX_CULL_DISTANCES_EXT",
+        0x82F9,
+        "GL_MAX_CULL_DISTANCES_EXT",
     },
     {
-        0x82FA, "GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT",
+        0x82FA,
+        "GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT",
     },
     {
-        0x82FB, "GL_CONTEXT_RELEASE_BEHAVIOR_KHR",
+        0x82FB,
+        "GL_CONTEXT_RELEASE_BEHAVIOR_KHR",
     },
     {
-        0x82FC, "GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR",
+        0x82FC,
+        "GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_KHR",
     },
     {
-        0x8363, "GL_UNSIGNED_SHORT_5_6_5",
+        0x8363,
+        "GL_UNSIGNED_SHORT_5_6_5",
     },
     {
-        0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT",
+        0x8365,
+        "GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT",
     },
     {
-        0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT",
+        0x8366,
+        "GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT",
     },
     {
-        0x8368, "GL_UNSIGNED_INT_2_10_10_10_REV_EXT",
+        0x8368,
+        "GL_UNSIGNED_INT_2_10_10_10_REV_EXT",
     },
     {
-        0x8370, "GL_MIRRORED_REPEAT",
+        0x8370,
+        "GL_MIRRORED_REPEAT",
     },
     {
-        0x83F0, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT",
+        0x83F0,
+        "GL_COMPRESSED_RGB_S3TC_DXT1_EXT",
     },
     {
-        0x83F1, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT",
+        0x83F1,
+        "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT",
     },
     {
-        0x83F2, "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE",
+        0x83F2,
+        "GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE",
     },
     {
-        0x83F3, "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE",
+        0x83F3,
+        "GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE",
     },
     {
-        0x83F9, "GL_PERFQUERY_DONOT_FLUSH_INTEL",
+        0x83F9,
+        "GL_PERFQUERY_DONOT_FLUSH_INTEL",
     },
     {
-        0x83FA, "GL_PERFQUERY_FLUSH_INTEL",
+        0x83FA,
+        "GL_PERFQUERY_FLUSH_INTEL",
     },
     {
-        0x83FB, "GL_PERFQUERY_WAIT_INTEL",
+        0x83FB,
+        "GL_PERFQUERY_WAIT_INTEL",
     },
     {
-        0x83FC, "GL_BLACKHOLE_RENDER_INTEL",
+        0x83FC,
+        "GL_BLACKHOLE_RENDER_INTEL",
     },
     {
-        0x83FE, "GL_CONSERVATIVE_RASTERIZATION_INTEL",
+        0x83FE,
+        "GL_CONSERVATIVE_RASTERIZATION_INTEL",
     },
     {
-        0x846D, "GL_ALIASED_POINT_SIZE_RANGE",
+        0x846D,
+        "GL_ALIASED_POINT_SIZE_RANGE",
     },
     {
-        0x846E, "GL_ALIASED_LINE_WIDTH_RANGE",
+        0x846E,
+        "GL_ALIASED_LINE_WIDTH_RANGE",
     },
     {
-        0x84C0, "GL_TEXTURE0",
+        0x84C0,
+        "GL_TEXTURE0",
     },
     {
-        0x84C1, "GL_TEXTURE1",
+        0x84C1,
+        "GL_TEXTURE1",
     },
     {
-        0x84C2, "GL_TEXTURE2",
+        0x84C2,
+        "GL_TEXTURE2",
     },
     {
-        0x84C3, "GL_TEXTURE3",
+        0x84C3,
+        "GL_TEXTURE3",
     },
     {
-        0x84C4, "GL_TEXTURE4",
+        0x84C4,
+        "GL_TEXTURE4",
     },
     {
-        0x84C5, "GL_TEXTURE5",
+        0x84C5,
+        "GL_TEXTURE5",
     },
     {
-        0x84C6, "GL_TEXTURE6",
+        0x84C6,
+        "GL_TEXTURE6",
     },
     {
-        0x84C7, "GL_TEXTURE7",
+        0x84C7,
+        "GL_TEXTURE7",
     },
     {
-        0x84C8, "GL_TEXTURE8",
+        0x84C8,
+        "GL_TEXTURE8",
     },
     {
-        0x84C9, "GL_TEXTURE9",
+        0x84C9,
+        "GL_TEXTURE9",
     },
     {
-        0x84CA, "GL_TEXTURE10",
+        0x84CA,
+        "GL_TEXTURE10",
     },
     {
-        0x84CB, "GL_TEXTURE11",
+        0x84CB,
+        "GL_TEXTURE11",
     },
     {
-        0x84CC, "GL_TEXTURE12",
+        0x84CC,
+        "GL_TEXTURE12",
     },
     {
-        0x84CD, "GL_TEXTURE13",
+        0x84CD,
+        "GL_TEXTURE13",
     },
     {
-        0x84CE, "GL_TEXTURE14",
+        0x84CE,
+        "GL_TEXTURE14",
     },
     {
-        0x84CF, "GL_TEXTURE15",
+        0x84CF,
+        "GL_TEXTURE15",
     },
     {
-        0x84D0, "GL_TEXTURE16",
+        0x84D0,
+        "GL_TEXTURE16",
     },
     {
-        0x84D1, "GL_TEXTURE17",
+        0x84D1,
+        "GL_TEXTURE17",
     },
     {
-        0x84D2, "GL_TEXTURE18",
+        0x84D2,
+        "GL_TEXTURE18",
     },
     {
-        0x84D3, "GL_TEXTURE19",
+        0x84D3,
+        "GL_TEXTURE19",
     },
     {
-        0x84D4, "GL_TEXTURE20",
+        0x84D4,
+        "GL_TEXTURE20",
     },
     {
-        0x84D5, "GL_TEXTURE21",
+        0x84D5,
+        "GL_TEXTURE21",
     },
     {
-        0x84D6, "GL_TEXTURE22",
+        0x84D6,
+        "GL_TEXTURE22",
     },
     {
-        0x84D7, "GL_TEXTURE23",
+        0x84D7,
+        "GL_TEXTURE23",
     },
     {
-        0x84D8, "GL_TEXTURE24",
+        0x84D8,
+        "GL_TEXTURE24",
     },
     {
-        0x84D9, "GL_TEXTURE25",
+        0x84D9,
+        "GL_TEXTURE25",
     },
     {
-        0x84DA, "GL_TEXTURE26",
+        0x84DA,
+        "GL_TEXTURE26",
     },
     {
-        0x84DB, "GL_TEXTURE27",
+        0x84DB,
+        "GL_TEXTURE27",
     },
     {
-        0x84DC, "GL_TEXTURE28",
+        0x84DC,
+        "GL_TEXTURE28",
     },
     {
-        0x84DD, "GL_TEXTURE29",
+        0x84DD,
+        "GL_TEXTURE29",
     },
     {
-        0x84DE, "GL_TEXTURE30",
+        0x84DE,
+        "GL_TEXTURE30",
     },
     {
-        0x84DF, "GL_TEXTURE31",
+        0x84DF,
+        "GL_TEXTURE31",
     },
     {
-        0x84E0, "GL_ACTIVE_TEXTURE",
+        0x84E0,
+        "GL_ACTIVE_TEXTURE",
     },
     {
-        0x84E3, "GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV",
+        0x84E3,
+        "GL_PATH_TRANSPOSE_MODELVIEW_MATRIX_NV",
     },
     {
-        0x84E4, "GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV",
+        0x84E4,
+        "GL_PATH_TRANSPOSE_PROJECTION_MATRIX_NV",
     },
     {
-        0x84E8, "GL_MAX_RENDERBUFFER_SIZE",
+        0x84E8,
+        "GL_MAX_RENDERBUFFER_SIZE",
     },
     {
-        0x84F2, "GL_ALL_COMPLETED_NV",
+        0x84F2,
+        "GL_ALL_COMPLETED_NV",
     },
     {
-        0x84F3, "GL_FENCE_STATUS_NV",
+        0x84F3,
+        "GL_FENCE_STATUS_NV",
     },
     {
-        0x84F4, "GL_FENCE_CONDITION_NV",
+        0x84F4,
+        "GL_FENCE_CONDITION_NV",
     },
     {
-        0x84F5, "GL_TEXTURE_RECTANGLE_ARB",
+        0x84F5,
+        "GL_TEXTURE_RECTANGLE_ARB",
     },
     {
-        0x84F6, "GL_TEXTURE_BINDING_RECTANGLE_ARB",
+        0x84F6,
+        "GL_TEXTURE_BINDING_RECTANGLE_ARB",
     },
     {
-        0x84F7, "GL_COMMANDS_COMPLETED_CHROMIUM",
+        0x84F7,
+        "GL_COMMANDS_COMPLETED_CHROMIUM",
     },
     {
-        0x84F8, "GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM",
+        0x84F8,
+        "GL_READBACK_SHADOW_COPIES_UPDATED_CHROMIUM",
     },
     {
-        0x84F9, "GL_DEPTH_STENCIL_OES",
+        0x84F9,
+        "GL_DEPTH_STENCIL_OES",
     },
     {
-        0x84FA, "GL_UNSIGNED_INT_24_8_OES",
+        0x84FA,
+        "GL_UNSIGNED_INT_24_8_OES",
     },
     {
-        0x84FD, "GL_MAX_TEXTURE_LOD_BIAS",
+        0x84FD,
+        "GL_MAX_TEXTURE_LOD_BIAS",
     },
     {
-        0x84FE, "GL_TEXTURE_MAX_ANISOTROPY_EXT",
+        0x84FE,
+        "GL_TEXTURE_MAX_ANISOTROPY_EXT",
     },
     {
-        0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT",
+        0x84FF,
+        "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT",
     },
     {
-        0x8507, "GL_INCR_WRAP",
+        0x8507,
+        "GL_INCR_WRAP",
     },
     {
-        0x8508, "GL_DECR_WRAP",
+        0x8508,
+        "GL_DECR_WRAP",
     },
     {
-        0x8513, "GL_TEXTURE_CUBE_MAP",
+        0x8513,
+        "GL_TEXTURE_CUBE_MAP",
     },
     {
-        0x8514, "GL_TEXTURE_BINDING_CUBE_MAP",
+        0x8514,
+        "GL_TEXTURE_BINDING_CUBE_MAP",
     },
     {
-        0x8515, "GL_TEXTURE_CUBE_MAP_POSITIVE_X",
+        0x8515,
+        "GL_TEXTURE_CUBE_MAP_POSITIVE_X",
     },
     {
-        0x8516, "GL_TEXTURE_CUBE_MAP_NEGATIVE_X",
+        0x8516,
+        "GL_TEXTURE_CUBE_MAP_NEGATIVE_X",
     },
     {
-        0x8517, "GL_TEXTURE_CUBE_MAP_POSITIVE_Y",
+        0x8517,
+        "GL_TEXTURE_CUBE_MAP_POSITIVE_Y",
     },
     {
-        0x8518, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y",
+        0x8518,
+        "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y",
     },
     {
-        0x8519, "GL_TEXTURE_CUBE_MAP_POSITIVE_Z",
+        0x8519,
+        "GL_TEXTURE_CUBE_MAP_POSITIVE_Z",
     },
     {
-        0x851A, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z",
+        0x851A,
+        "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z",
     },
     {
-        0x851C, "GL_MAX_CUBE_MAP_TEXTURE_SIZE",
+        0x851C,
+        "GL_MAX_CUBE_MAP_TEXTURE_SIZE",
     },
     {
-        0x8576, "GL_CONSTANT_CHROMIUM",
+        0x8576,
+        "GL_CONSTANT_CHROMIUM",
     },
     {
-        0x8589, "GL_SRC1_ALPHA_EXT",
+        0x8589,
+        "GL_SRC1_ALPHA_EXT",
     },
     {
-        0x85B5, "GL_VERTEX_ARRAY_BINDING_OES",
+        0x85B5,
+        "GL_VERTEX_ARRAY_BINDING_OES",
     },
     {
-        0x85BA, "GL_UNSIGNED_SHORT_8_8_APPLE",
+        0x85BA,
+        "GL_UNSIGNED_SHORT_8_8_APPLE",
     },
     {
-        0x85BB, "GL_UNSIGNED_SHORT_8_8_REV_APPLE",
+        0x85BB,
+        "GL_UNSIGNED_SHORT_8_8_REV_APPLE",
     },
     {
-        0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED",
+        0x8622,
+        "GL_VERTEX_ATTRIB_ARRAY_ENABLED",
     },
     {
-        0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE",
+        0x8623,
+        "GL_VERTEX_ATTRIB_ARRAY_SIZE",
     },
     {
-        0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE",
+        0x8624,
+        "GL_VERTEX_ATTRIB_ARRAY_STRIDE",
     },
     {
-        0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE",
+        0x8625,
+        "GL_VERTEX_ATTRIB_ARRAY_TYPE",
     },
     {
-        0x8626, "GL_CURRENT_VERTEX_ATTRIB",
+        0x8626,
+        "GL_CURRENT_VERTEX_ATTRIB",
     },
     {
-        0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER",
+        0x8645,
+        "GL_VERTEX_ATTRIB_ARRAY_POINTER",
     },
     {
-        0x86A1, "GL_TEXTURE_COMPRESSED",
+        0x86A1,
+        "GL_TEXTURE_COMPRESSED",
     },
     {
-        0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS",
+        0x86A2,
+        "GL_NUM_COMPRESSED_TEXTURE_FORMATS",
     },
     {
-        0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS",
+        0x86A3,
+        "GL_COMPRESSED_TEXTURE_FORMATS",
     },
     {
-        0x8740, "GL_Z400_BINARY_AMD",
+        0x8740,
+        "GL_Z400_BINARY_AMD",
     },
     {
-        0x8741, "GL_PROGRAM_BINARY_LENGTH_OES",
+        0x8741,
+        "GL_PROGRAM_BINARY_LENGTH_OES",
     },
     {
-        0x8743, "GL_MIRROR_CLAMP_TO_EDGE_EXT",
+        0x8743,
+        "GL_MIRROR_CLAMP_TO_EDGE_EXT",
     },
     {
-        0x875F, "GL_PROGRAM_BINARY_FORMAT_MESA",
+        0x875F,
+        "GL_PROGRAM_BINARY_FORMAT_MESA",
     },
     {
-        0x8764, "GL_BUFFER_SIZE",
+        0x8764,
+        "GL_BUFFER_SIZE",
     },
     {
-        0x8765, "GL_BUFFER_USAGE",
+        0x8765,
+        "GL_BUFFER_USAGE",
     },
     {
-        0x87EE, "GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD",
+        0x87EE,
+        "GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD",
     },
     {
-        0x87F9, "GL_3DC_X_AMD",
+        0x87F9,
+        "GL_3DC_X_AMD",
     },
     {
-        0x87FA, "GL_3DC_XY_AMD",
+        0x87FA,
+        "GL_3DC_XY_AMD",
     },
     {
-        0x87FE, "GL_NUM_PROGRAM_BINARY_FORMATS_OES",
+        0x87FE,
+        "GL_NUM_PROGRAM_BINARY_FORMATS_OES",
     },
     {
-        0x87FF, "GL_PROGRAM_BINARY_FORMATS_OES",
+        0x87FF,
+        "GL_PROGRAM_BINARY_FORMATS_OES",
     },
     {
-        0x8800, "GL_STENCIL_BACK_FUNC",
+        0x8800,
+        "GL_STENCIL_BACK_FUNC",
     },
     {
-        0x8801, "GL_STENCIL_BACK_FAIL",
+        0x8801,
+        "GL_STENCIL_BACK_FAIL",
     },
     {
-        0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL",
+        0x8802,
+        "GL_STENCIL_BACK_PASS_DEPTH_FAIL",
     },
     {
-        0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS",
+        0x8803,
+        "GL_STENCIL_BACK_PASS_DEPTH_PASS",
     },
     {
-        0x8814, "GL_RGBA32F_EXT",
+        0x8814,
+        "GL_RGBA32F_EXT",
     },
     {
-        0x8815, "GL_RGB32F_EXT",
+        0x8815,
+        "GL_RGB32F_EXT",
     },
     {
-        0x8816, "GL_ALPHA32F_EXT",
+        0x8816,
+        "GL_ALPHA32F_EXT",
     },
     {
-        0x8818, "GL_LUMINANCE32F_EXT",
+        0x8818,
+        "GL_LUMINANCE32F_EXT",
     },
     {
-        0x8819, "GL_LUMINANCE_ALPHA32F_EXT",
+        0x8819,
+        "GL_LUMINANCE_ALPHA32F_EXT",
     },
     {
-        0x881A, "GL_RGBA16F_EXT",
+        0x881A,
+        "GL_RGBA16F_EXT",
     },
     {
-        0x881B, "GL_RGB16F_EXT",
+        0x881B,
+        "GL_RGB16F_EXT",
     },
     {
-        0x881C, "GL_ALPHA16F_EXT",
+        0x881C,
+        "GL_ALPHA16F_EXT",
     },
     {
-        0x881E, "GL_LUMINANCE16F_EXT",
+        0x881E,
+        "GL_LUMINANCE16F_EXT",
     },
     {
-        0x881F, "GL_LUMINANCE_ALPHA16F_EXT",
+        0x881F,
+        "GL_LUMINANCE_ALPHA16F_EXT",
     },
     {
-        0x8823, "GL_WRITEONLY_RENDERING_QCOM",
+        0x8823,
+        "GL_WRITEONLY_RENDERING_QCOM",
     },
     {
-        0x8824, "GL_MAX_DRAW_BUFFERS_EXT",
+        0x8824,
+        "GL_MAX_DRAW_BUFFERS_EXT",
     },
     {
-        0x8825, "GL_DRAW_BUFFER0_EXT",
+        0x8825,
+        "GL_DRAW_BUFFER0_EXT",
     },
     {
-        0x8826, "GL_DRAW_BUFFER1_EXT",
+        0x8826,
+        "GL_DRAW_BUFFER1_EXT",
     },
     {
-        0x8827, "GL_DRAW_BUFFER2_EXT",
+        0x8827,
+        "GL_DRAW_BUFFER2_EXT",
     },
     {
-        0x8828, "GL_DRAW_BUFFER3_EXT",
+        0x8828,
+        "GL_DRAW_BUFFER3_EXT",
     },
     {
-        0x8829, "GL_DRAW_BUFFER4_EXT",
+        0x8829,
+        "GL_DRAW_BUFFER4_EXT",
     },
     {
-        0x882A, "GL_DRAW_BUFFER5_EXT",
+        0x882A,
+        "GL_DRAW_BUFFER5_EXT",
     },
     {
-        0x882B, "GL_DRAW_BUFFER6_EXT",
+        0x882B,
+        "GL_DRAW_BUFFER6_EXT",
     },
     {
-        0x882C, "GL_DRAW_BUFFER7_EXT",
+        0x882C,
+        "GL_DRAW_BUFFER7_EXT",
     },
     {
-        0x882D, "GL_DRAW_BUFFER8_EXT",
+        0x882D,
+        "GL_DRAW_BUFFER8_EXT",
     },
     {
-        0x882E, "GL_DRAW_BUFFER9_EXT",
+        0x882E,
+        "GL_DRAW_BUFFER9_EXT",
     },
     {
-        0x882F, "GL_DRAW_BUFFER10_EXT",
+        0x882F,
+        "GL_DRAW_BUFFER10_EXT",
     },
     {
-        0x8830, "GL_DRAW_BUFFER11_EXT",
+        0x8830,
+        "GL_DRAW_BUFFER11_EXT",
     },
     {
-        0x8831, "GL_DRAW_BUFFER12_EXT",
+        0x8831,
+        "GL_DRAW_BUFFER12_EXT",
     },
     {
-        0x8832, "GL_DRAW_BUFFER13_EXT",
+        0x8832,
+        "GL_DRAW_BUFFER13_EXT",
     },
     {
-        0x8833, "GL_DRAW_BUFFER14_EXT",
+        0x8833,
+        "GL_DRAW_BUFFER14_EXT",
     },
     {
-        0x8834, "GL_DRAW_BUFFER15_EXT",
+        0x8834,
+        "GL_DRAW_BUFFER15_EXT",
     },
     {
-        0x883D, "GL_BLEND_EQUATION_ALPHA",
+        0x883D,
+        "GL_BLEND_EQUATION_ALPHA",
     },
     {
-        0x884A, "GL_TEXTURE_DEPTH_SIZE",
+        0x884A,
+        "GL_TEXTURE_DEPTH_SIZE",
     },
     {
-        0x884C, "GL_TEXTURE_COMPARE_MODE_EXT",
+        0x884C,
+        "GL_TEXTURE_COMPARE_MODE_EXT",
     },
     {
-        0x884D, "GL_TEXTURE_COMPARE_FUNC_EXT",
+        0x884D,
+        "GL_TEXTURE_COMPARE_FUNC_EXT",
     },
     {
-        0x884E, "GL_COMPARE_REF_TO_TEXTURE_EXT",
+        0x884E,
+        "GL_COMPARE_REF_TO_TEXTURE_EXT",
     },
     {
-        0x8864, "GL_QUERY_COUNTER_BITS_EXT",
+        0x8864,
+        "GL_QUERY_COUNTER_BITS_EXT",
     },
     {
-        0x8865, "GL_CURRENT_QUERY_EXT",
+        0x8865,
+        "GL_CURRENT_QUERY_EXT",
     },
     {
-        0x8866, "GL_QUERY_RESULT_EXT",
+        0x8866,
+        "GL_QUERY_RESULT_EXT",
     },
     {
-        0x8867, "GL_QUERY_RESULT_AVAILABLE_EXT",
+        0x8867,
+        "GL_QUERY_RESULT_AVAILABLE_EXT",
     },
     {
-        0x8868, "GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT",
+        0x8868,
+        "GL_QUERY_RESULT_AVAILABLE_NO_FLUSH_CHROMIUM_EXT",
     },
     {
-        0x8869, "GL_MAX_VERTEX_ATTRIBS",
+        0x8869,
+        "GL_MAX_VERTEX_ATTRIBS",
     },
     {
-        0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED",
+        0x886A,
+        "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED",
     },
     {
-        0x886C, "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES",
+        0x886C,
+        "GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_OES",
     },
     {
-        0x886D, "GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES",
+        0x886D,
+        "GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_OES",
     },
     {
-        0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS",
+        0x8872,
+        "GL_MAX_TEXTURE_IMAGE_UNITS",
     },
     {
-        0x887F, "GL_GEOMETRY_SHADER_INVOCATIONS_OES",
+        0x887F,
+        "GL_GEOMETRY_SHADER_INVOCATIONS_OES",
     },
     {
-        0x8892, "GL_ARRAY_BUFFER",
+        0x8892,
+        "GL_ARRAY_BUFFER",
     },
     {
-        0x8893, "GL_ELEMENT_ARRAY_BUFFER",
+        0x8893,
+        "GL_ELEMENT_ARRAY_BUFFER",
     },
     {
-        0x8894, "GL_ARRAY_BUFFER_BINDING",
+        0x8894,
+        "GL_ARRAY_BUFFER_BINDING",
     },
     {
-        0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING",
+        0x8895,
+        "GL_ELEMENT_ARRAY_BUFFER_BINDING",
     },
     {
-        0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
+        0x889F,
+        "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING",
     },
     {
-        0x88B8, "GL_READ_ONLY",
+        0x88B8,
+        "GL_READ_ONLY",
     },
     {
-        0x88B9, "GL_WRITE_ONLY_OES",
+        0x88B9,
+        "GL_WRITE_ONLY_OES",
     },
     {
-        0x88BA, "GL_READ_WRITE",
+        0x88BA,
+        "GL_READ_WRITE",
     },
     {
-        0x88BB, "GL_BUFFER_ACCESS_OES",
+        0x88BB,
+        "GL_BUFFER_ACCESS_OES",
     },
     {
-        0x88BC, "GL_BUFFER_MAPPED_OES",
+        0x88BC,
+        "GL_BUFFER_MAPPED_OES",
     },
     {
-        0x88BD, "GL_BUFFER_MAP_POINTER_OES",
+        0x88BD,
+        "GL_BUFFER_MAP_POINTER_OES",
     },
     {
-        0x88BF, "GL_TIME_ELAPSED_EXT",
+        0x88BF,
+        "GL_TIME_ELAPSED_EXT",
     },
     {
-        0x88E0, "GL_STREAM_DRAW",
+        0x88E0,
+        "GL_STREAM_DRAW",
     },
     {
-        0x88E1, "GL_STREAM_READ",
+        0x88E1,
+        "GL_STREAM_READ",
     },
     {
-        0x88E2, "GL_STREAM_COPY",
+        0x88E2,
+        "GL_STREAM_COPY",
     },
     {
-        0x88E4, "GL_STATIC_DRAW",
+        0x88E4,
+        "GL_STATIC_DRAW",
     },
     {
-        0x88E5, "GL_STATIC_READ",
+        0x88E5,
+        "GL_STATIC_READ",
     },
     {
-        0x88E6, "GL_STATIC_COPY",
+        0x88E6,
+        "GL_STATIC_COPY",
     },
     {
-        0x88E8, "GL_DYNAMIC_DRAW",
+        0x88E8,
+        "GL_DYNAMIC_DRAW",
     },
     {
-        0x88E9, "GL_DYNAMIC_READ",
+        0x88E9,
+        "GL_DYNAMIC_READ",
     },
     {
-        0x88EA, "GL_DYNAMIC_COPY",
+        0x88EA,
+        "GL_DYNAMIC_COPY",
     },
     {
-        0x88EB, "GL_PIXEL_PACK_BUFFER_NV",
+        0x88EB,
+        "GL_PIXEL_PACK_BUFFER_NV",
     },
     {
-        0x88EC, "GL_PIXEL_UNPACK_BUFFER_NV",
+        0x88EC,
+        "GL_PIXEL_UNPACK_BUFFER_NV",
     },
     {
-        0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING_NV",
+        0x88ED,
+        "GL_PIXEL_PACK_BUFFER_BINDING_NV",
     },
     {
-        0x88EE, "GL_ETC1_SRGB8_NV",
+        0x88EE,
+        "GL_ETC1_SRGB8_NV",
     },
     {
-        0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING_NV",
+        0x88EF,
+        "GL_PIXEL_UNPACK_BUFFER_BINDING_NV",
     },
     {
-        0x88F0, "GL_DEPTH24_STENCIL8_OES",
+        0x88F0,
+        "GL_DEPTH24_STENCIL8_OES",
     },
     {
-        0x88F1, "GL_TEXTURE_STENCIL_SIZE",
+        0x88F1,
+        "GL_TEXTURE_STENCIL_SIZE",
     },
     {
-        0x88F9, "GL_SRC1_COLOR_EXT",
+        0x88F9,
+        "GL_SRC1_COLOR_EXT",
     },
     {
-        0x88FA, "GL_ONE_MINUS_SRC1_COLOR_EXT",
+        0x88FA,
+        "GL_ONE_MINUS_SRC1_COLOR_EXT",
     },
     {
-        0x88FB, "GL_ONE_MINUS_SRC1_ALPHA_EXT",
+        0x88FB,
+        "GL_ONE_MINUS_SRC1_ALPHA_EXT",
     },
     {
-        0x88FC, "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT",
+        0x88FC,
+        "GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT",
     },
     {
-        0x88FD, "GL_VERTEX_ATTRIB_ARRAY_INTEGER",
+        0x88FD,
+        "GL_VERTEX_ATTRIB_ARRAY_INTEGER",
     },
     {
-        0x88FE, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE",
+        0x88FE,
+        "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE",
     },
     {
-        0x88FF, "GL_MAX_ARRAY_TEXTURE_LAYERS",
+        0x88FF,
+        "GL_MAX_ARRAY_TEXTURE_LAYERS",
     },
     {
-        0x8904, "GL_MIN_PROGRAM_TEXEL_OFFSET",
+        0x8904,
+        "GL_MIN_PROGRAM_TEXEL_OFFSET",
     },
     {
-        0x8905, "GL_MAX_PROGRAM_TEXEL_OFFSET",
+        0x8905,
+        "GL_MAX_PROGRAM_TEXEL_OFFSET",
     },
     {
-        0x8914, "GL_SAMPLES_PASSED_ARB",
+        0x8914,
+        "GL_SAMPLES_PASSED_ARB",
     },
     {
-        0x8916, "GL_GEOMETRY_LINKED_VERTICES_OUT_OES",
+        0x8916,
+        "GL_GEOMETRY_LINKED_VERTICES_OUT_OES",
     },
     {
-        0x8917, "GL_GEOMETRY_LINKED_INPUT_TYPE_OES",
+        0x8917,
+        "GL_GEOMETRY_LINKED_INPUT_TYPE_OES",
     },
     {
-        0x8918, "GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES",
+        0x8918,
+        "GL_GEOMETRY_LINKED_OUTPUT_TYPE_OES",
     },
     {
-        0x8919, "GL_SAMPLER_BINDING",
+        0x8919,
+        "GL_SAMPLER_BINDING",
     },
     {
-        0x8A11, "GL_UNIFORM_BUFFER",
+        0x8A11,
+        "GL_UNIFORM_BUFFER",
     },
     {
-        0x8A1F, "GL_RGB_422_APPLE",
+        0x8A1F,
+        "GL_RGB_422_APPLE",
     },
     {
-        0x8A28, "GL_UNIFORM_BUFFER_BINDING",
+        0x8A28,
+        "GL_UNIFORM_BUFFER_BINDING",
     },
     {
-        0x8A29, "GL_UNIFORM_BUFFER_START",
+        0x8A29,
+        "GL_UNIFORM_BUFFER_START",
     },
     {
-        0x8A2A, "GL_UNIFORM_BUFFER_SIZE",
+        0x8A2A,
+        "GL_UNIFORM_BUFFER_SIZE",
     },
     {
-        0x8A2B, "GL_MAX_VERTEX_UNIFORM_BLOCKS",
+        0x8A2B,
+        "GL_MAX_VERTEX_UNIFORM_BLOCKS",
     },
     {
-        0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES",
+        0x8A2C,
+        "GL_MAX_GEOMETRY_UNIFORM_BLOCKS_OES",
     },
     {
-        0x8A2D, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS",
+        0x8A2D,
+        "GL_MAX_FRAGMENT_UNIFORM_BLOCKS",
     },
     {
-        0x8A2E, "GL_MAX_COMBINED_UNIFORM_BLOCKS",
+        0x8A2E,
+        "GL_MAX_COMBINED_UNIFORM_BLOCKS",
     },
     {
-        0x8A2F, "GL_MAX_UNIFORM_BUFFER_BINDINGS",
+        0x8A2F,
+        "GL_MAX_UNIFORM_BUFFER_BINDINGS",
     },
     {
-        0x8A30, "GL_MAX_UNIFORM_BLOCK_SIZE",
+        0x8A30,
+        "GL_MAX_UNIFORM_BLOCK_SIZE",
     },
     {
-        0x8A31, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
+        0x8A31,
+        "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS",
     },
     {
-        0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES",
+        0x8A32,
+        "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_OES",
     },
     {
-        0x8A33, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
+        0x8A33,
+        "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS",
     },
     {
-        0x8A34, "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT",
+        0x8A34,
+        "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT",
     },
     {
-        0x8A35, "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH",
+        0x8A35,
+        "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH",
     },
     {
-        0x8A36, "GL_ACTIVE_UNIFORM_BLOCKS",
+        0x8A36,
+        "GL_ACTIVE_UNIFORM_BLOCKS",
     },
     {
-        0x8A37, "GL_UNIFORM_TYPE",
+        0x8A37,
+        "GL_UNIFORM_TYPE",
     },
     {
-        0x8A38, "GL_UNIFORM_SIZE",
+        0x8A38,
+        "GL_UNIFORM_SIZE",
     },
     {
-        0x8A39, "GL_UNIFORM_NAME_LENGTH",
+        0x8A39,
+        "GL_UNIFORM_NAME_LENGTH",
     },
     {
-        0x8A3A, "GL_UNIFORM_BLOCK_INDEX",
+        0x8A3A,
+        "GL_UNIFORM_BLOCK_INDEX",
     },
     {
-        0x8A3B, "GL_UNIFORM_OFFSET",
+        0x8A3B,
+        "GL_UNIFORM_OFFSET",
     },
     {
-        0x8A3C, "GL_UNIFORM_ARRAY_STRIDE",
+        0x8A3C,
+        "GL_UNIFORM_ARRAY_STRIDE",
     },
     {
-        0x8A3D, "GL_UNIFORM_MATRIX_STRIDE",
+        0x8A3D,
+        "GL_UNIFORM_MATRIX_STRIDE",
     },
     {
-        0x8A3E, "GL_UNIFORM_IS_ROW_MAJOR",
+        0x8A3E,
+        "GL_UNIFORM_IS_ROW_MAJOR",
     },
     {
-        0x8A3F, "GL_UNIFORM_BLOCK_BINDING",
+        0x8A3F,
+        "GL_UNIFORM_BLOCK_BINDING",
     },
     {
-        0x8A40, "GL_UNIFORM_BLOCK_DATA_SIZE",
+        0x8A40,
+        "GL_UNIFORM_BLOCK_DATA_SIZE",
     },
     {
-        0x8A41, "GL_UNIFORM_BLOCK_NAME_LENGTH",
+        0x8A41,
+        "GL_UNIFORM_BLOCK_NAME_LENGTH",
     },
     {
-        0x8A42, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS",
+        0x8A42,
+        "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS",
     },
     {
-        0x8A43, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
+        0x8A43,
+        "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES",
     },
     {
-        0x8A44, "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
+        0x8A44,
+        "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER",
     },
     {
-        0x8A46, "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
+        0x8A46,
+        "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER",
     },
     {
-        0x8A48, "GL_TEXTURE_SRGB_DECODE_EXT",
+        0x8A48,
+        "GL_TEXTURE_SRGB_DECODE_EXT",
     },
     {
-        0x8A49, "GL_DECODE_EXT",
+        0x8A49,
+        "GL_DECODE_EXT",
     },
     {
-        0x8A4A, "GL_SKIP_DECODE_EXT",
+        0x8A4A,
+        "GL_SKIP_DECODE_EXT",
     },
     {
-        0x8A4F, "GL_PROGRAM_PIPELINE_OBJECT_EXT",
+        0x8A4F,
+        "GL_PROGRAM_PIPELINE_OBJECT_EXT",
     },
     {
-        0x8A51, "GL_RGB_RAW_422_APPLE",
+        0x8A51,
+        "GL_RGB_RAW_422_APPLE",
     },
     {
-        0x8A52, "GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT",
+        0x8A52,
+        "GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT",
     },
     {
-        0x8A53, "GL_SYNC_OBJECT_APPLE",
+        0x8A53,
+        "GL_SYNC_OBJECT_APPLE",
     },
     {
-        0x8A54, "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT",
+        0x8A54,
+        "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT",
     },
     {
-        0x8A55, "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT",
+        0x8A55,
+        "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT",
     },
     {
-        0x8A56, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT",
+        0x8A56,
+        "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT",
     },
     {
-        0x8A57, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT",
+        0x8A57,
+        "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT",
     },
     {
-        0x8AF0, "GL_TEXTURE_FILTERING_HINT_CHROMIUM",
+        0x8AF0,
+        "GL_TEXTURE_FILTERING_HINT_CHROMIUM",
     },
     {
-        0x8AF1, "GL_COLOR_SPACE_UNSPECIFIED_CHROMIUM",
+        0x8AF1,
+        "GL_COLOR_SPACE_UNSPECIFIED_CHROMIUM",
     },
     {
-        0x8AF2, "GL_COLOR_SPACE_SCRGB_LINEAR_CHROMIUM",
+        0x8AF2,
+        "GL_COLOR_SPACE_SCRGB_LINEAR_CHROMIUM",
     },
     {
-        0x8AF3, "GL_COLOR_SPACE_SRGB_CHROMIUM",
+        0x8AF3,
+        "GL_COLOR_SPACE_SRGB_CHROMIUM",
     },
     {
-        0x8AF4, "GL_COLOR_SPACE_DISPLAY_P3_CHROMIUM",
+        0x8AF4,
+        "GL_COLOR_SPACE_DISPLAY_P3_CHROMIUM",
     },
     {
-        0x8AF5, "GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM",
+        0x8AF5,
+        "GL_SHARED_IMAGE_ACCESS_MODE_READ_CHROMIUM",
     },
     {
-        0x8AF6, "GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM",
+        0x8AF6,
+        "GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM",
     },
     {
-        0x8B30, "GL_FRAGMENT_SHADER",
+        0x8B30,
+        "GL_FRAGMENT_SHADER",
     },
     {
-        0x8B31, "GL_VERTEX_SHADER",
+        0x8B31,
+        "GL_VERTEX_SHADER",
     },
     {
-        0x8B40, "GL_PROGRAM_OBJECT_EXT",
+        0x8B40,
+        "GL_PROGRAM_OBJECT_EXT",
     },
     {
-        0x8B48, "GL_SHADER_OBJECT_EXT",
+        0x8B48,
+        "GL_SHADER_OBJECT_EXT",
     },
     {
-        0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS",
+        0x8B49,
+        "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS",
     },
     {
-        0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS",
+        0x8B4A,
+        "GL_MAX_VERTEX_UNIFORM_COMPONENTS",
     },
     {
-        0x8B4B, "GL_MAX_VARYING_COMPONENTS",
+        0x8B4B,
+        "GL_MAX_VARYING_COMPONENTS",
     },
     {
-        0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS",
+        0x8B4C,
+        "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS",
     },
     {
-        0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS",
+        0x8B4D,
+        "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS",
     },
     {
-        0x8B4F, "GL_SHADER_TYPE",
+        0x8B4F,
+        "GL_SHADER_TYPE",
     },
     {
-        0x8B50, "GL_FLOAT_VEC2",
+        0x8B50,
+        "GL_FLOAT_VEC2",
     },
     {
-        0x8B51, "GL_FLOAT_VEC3",
+        0x8B51,
+        "GL_FLOAT_VEC3",
     },
     {
-        0x8B52, "GL_FLOAT_VEC4",
+        0x8B52,
+        "GL_FLOAT_VEC4",
     },
     {
-        0x8B53, "GL_INT_VEC2",
+        0x8B53,
+        "GL_INT_VEC2",
     },
     {
-        0x8B54, "GL_INT_VEC3",
+        0x8B54,
+        "GL_INT_VEC3",
     },
     {
-        0x8B55, "GL_INT_VEC4",
+        0x8B55,
+        "GL_INT_VEC4",
     },
     {
-        0x8B56, "GL_BOOL",
+        0x8B56,
+        "GL_BOOL",
     },
     {
-        0x8B57, "GL_BOOL_VEC2",
+        0x8B57,
+        "GL_BOOL_VEC2",
     },
     {
-        0x8B58, "GL_BOOL_VEC3",
+        0x8B58,
+        "GL_BOOL_VEC3",
     },
     {
-        0x8B59, "GL_BOOL_VEC4",
+        0x8B59,
+        "GL_BOOL_VEC4",
     },
     {
-        0x8B5A, "GL_FLOAT_MAT2",
+        0x8B5A,
+        "GL_FLOAT_MAT2",
     },
     {
-        0x8B5B, "GL_FLOAT_MAT3",
+        0x8B5B,
+        "GL_FLOAT_MAT3",
     },
     {
-        0x8B5C, "GL_FLOAT_MAT4",
+        0x8B5C,
+        "GL_FLOAT_MAT4",
     },
     {
-        0x8B5E, "GL_SAMPLER_2D",
+        0x8B5E,
+        "GL_SAMPLER_2D",
     },
     {
-        0x8B5F, "GL_SAMPLER_3D_OES",
+        0x8B5F,
+        "GL_SAMPLER_3D_OES",
     },
     {
-        0x8B60, "GL_SAMPLER_CUBE",
+        0x8B60,
+        "GL_SAMPLER_CUBE",
     },
     {
-        0x8B62, "GL_SAMPLER_2D_SHADOW_EXT",
+        0x8B62,
+        "GL_SAMPLER_2D_SHADOW_EXT",
     },
     {
-        0x8B63, "GL_SAMPLER_2D_RECT_ARB",
+        0x8B63,
+        "GL_SAMPLER_2D_RECT_ARB",
     },
     {
-        0x8B65, "GL_FLOAT_MAT2x3_NV",
+        0x8B65,
+        "GL_FLOAT_MAT2x3_NV",
     },
     {
-        0x8B66, "GL_FLOAT_MAT2x4_NV",
+        0x8B66,
+        "GL_FLOAT_MAT2x4_NV",
     },
     {
-        0x8B67, "GL_FLOAT_MAT3x2_NV",
+        0x8B67,
+        "GL_FLOAT_MAT3x2_NV",
     },
     {
-        0x8B68, "GL_FLOAT_MAT3x4_NV",
+        0x8B68,
+        "GL_FLOAT_MAT3x4_NV",
     },
     {
-        0x8B69, "GL_FLOAT_MAT4x2_NV",
+        0x8B69,
+        "GL_FLOAT_MAT4x2_NV",
     },
     {
-        0x8B6A, "GL_FLOAT_MAT4x3_NV",
+        0x8B6A,
+        "GL_FLOAT_MAT4x3_NV",
     },
     {
-        0x8B80, "GL_DELETE_STATUS",
+        0x8B80,
+        "GL_DELETE_STATUS",
     },
     {
-        0x8B81, "GL_COMPILE_STATUS",
+        0x8B81,
+        "GL_COMPILE_STATUS",
     },
     {
-        0x8B82, "GL_LINK_STATUS",
+        0x8B82,
+        "GL_LINK_STATUS",
     },
     {
-        0x8B83, "GL_VALIDATE_STATUS",
+        0x8B83,
+        "GL_VALIDATE_STATUS",
     },
     {
-        0x8B84, "GL_INFO_LOG_LENGTH",
+        0x8B84,
+        "GL_INFO_LOG_LENGTH",
     },
     {
-        0x8B85, "GL_ATTACHED_SHADERS",
+        0x8B85,
+        "GL_ATTACHED_SHADERS",
     },
     {
-        0x8B86, "GL_ACTIVE_UNIFORMS",
+        0x8B86,
+        "GL_ACTIVE_UNIFORMS",
     },
     {
-        0x8B87, "GL_ACTIVE_UNIFORM_MAX_LENGTH",
+        0x8B87,
+        "GL_ACTIVE_UNIFORM_MAX_LENGTH",
     },
     {
-        0x8B88, "GL_SHADER_SOURCE_LENGTH",
+        0x8B88,
+        "GL_SHADER_SOURCE_LENGTH",
     },
     {
-        0x8B89, "GL_ACTIVE_ATTRIBUTES",
+        0x8B89,
+        "GL_ACTIVE_ATTRIBUTES",
     },
     {
-        0x8B8A, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH",
+        0x8B8A,
+        "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH",
     },
     {
-        0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
+        0x8B8B,
+        "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES",
     },
     {
-        0x8B8C, "GL_SHADING_LANGUAGE_VERSION",
+        0x8B8C,
+        "GL_SHADING_LANGUAGE_VERSION",
     },
     {
-        0x8B8D, "GL_CURRENT_PROGRAM",
+        0x8B8D,
+        "GL_CURRENT_PROGRAM",
     },
     {
-        0x8B90, "GL_PALETTE4_RGB8_OES",
+        0x8B90,
+        "GL_PALETTE4_RGB8_OES",
     },
     {
-        0x8B91, "GL_PALETTE4_RGBA8_OES",
+        0x8B91,
+        "GL_PALETTE4_RGBA8_OES",
     },
     {
-        0x8B92, "GL_PALETTE4_R5_G6_B5_OES",
+        0x8B92,
+        "GL_PALETTE4_R5_G6_B5_OES",
     },
     {
-        0x8B93, "GL_PALETTE4_RGBA4_OES",
+        0x8B93,
+        "GL_PALETTE4_RGBA4_OES",
     },
     {
-        0x8B94, "GL_PALETTE4_RGB5_A1_OES",
+        0x8B94,
+        "GL_PALETTE4_RGB5_A1_OES",
     },
     {
-        0x8B95, "GL_PALETTE8_RGB8_OES",
+        0x8B95,
+        "GL_PALETTE8_RGB8_OES",
     },
     {
-        0x8B96, "GL_PALETTE8_RGBA8_OES",
+        0x8B96,
+        "GL_PALETTE8_RGBA8_OES",
     },
     {
-        0x8B97, "GL_PALETTE8_R5_G6_B5_OES",
+        0x8B97,
+        "GL_PALETTE8_R5_G6_B5_OES",
     },
     {
-        0x8B98, "GL_PALETTE8_RGBA4_OES",
+        0x8B98,
+        "GL_PALETTE8_RGBA4_OES",
     },
     {
-        0x8B99, "GL_PALETTE8_RGB5_A1_OES",
+        0x8B99,
+        "GL_PALETTE8_RGB5_A1_OES",
     },
     {
-        0x8B9A, "GL_IMPLEMENTATION_COLOR_READ_TYPE",
+        0x8B9A,
+        "GL_IMPLEMENTATION_COLOR_READ_TYPE",
     },
     {
-        0x8B9B, "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
+        0x8B9B,
+        "GL_IMPLEMENTATION_COLOR_READ_FORMAT",
     },
     {
-        0x8BBB, "GL_FRAMEBUFFER_FLIP_Y_MESA",
+        0x8BBB,
+        "GL_FRAMEBUFFER_FLIP_Y_MESA",
     },
     {
-        0x8BC0, "GL_COUNTER_TYPE_AMD",
+        0x8BC0,
+        "GL_COUNTER_TYPE_AMD",
     },
     {
-        0x8BC1, "GL_COUNTER_RANGE_AMD",
+        0x8BC1,
+        "GL_COUNTER_RANGE_AMD",
     },
     {
-        0x8BC2, "GL_UNSIGNED_INT64_AMD",
+        0x8BC2,
+        "GL_UNSIGNED_INT64_AMD",
     },
     {
-        0x8BC3, "GL_PERCENTAGE_AMD",
+        0x8BC3,
+        "GL_PERCENTAGE_AMD",
     },
     {
-        0x8BC4, "GL_PERFMON_RESULT_AVAILABLE_AMD",
+        0x8BC4,
+        "GL_PERFMON_RESULT_AVAILABLE_AMD",
     },
     {
-        0x8BC5, "GL_PERFMON_RESULT_SIZE_AMD",
+        0x8BC5,
+        "GL_PERFMON_RESULT_SIZE_AMD",
     },
     {
-        0x8BC6, "GL_PERFMON_RESULT_AMD",
+        0x8BC6,
+        "GL_PERFMON_RESULT_AMD",
     },
     {
-        0x8BD2, "GL_TEXTURE_WIDTH_QCOM",
+        0x8BD2,
+        "GL_TEXTURE_WIDTH_QCOM",
     },
     {
-        0x8BD3, "GL_TEXTURE_HEIGHT_QCOM",
+        0x8BD3,
+        "GL_TEXTURE_HEIGHT_QCOM",
     },
     {
-        0x8BD4, "GL_TEXTURE_DEPTH_QCOM",
+        0x8BD4,
+        "GL_TEXTURE_DEPTH_QCOM",
     },
     {
-        0x8BD5, "GL_TEXTURE_INTERNAL_FORMAT_QCOM",
+        0x8BD5,
+        "GL_TEXTURE_INTERNAL_FORMAT_QCOM",
     },
     {
-        0x8BD6, "GL_TEXTURE_FORMAT_QCOM",
+        0x8BD6,
+        "GL_TEXTURE_FORMAT_QCOM",
     },
     {
-        0x8BD7, "GL_TEXTURE_TYPE_QCOM",
+        0x8BD7,
+        "GL_TEXTURE_TYPE_QCOM",
     },
     {
-        0x8BD8, "GL_TEXTURE_IMAGE_VALID_QCOM",
+        0x8BD8,
+        "GL_TEXTURE_IMAGE_VALID_QCOM",
     },
     {
-        0x8BD9, "GL_TEXTURE_NUM_LEVELS_QCOM",
+        0x8BD9,
+        "GL_TEXTURE_NUM_LEVELS_QCOM",
     },
     {
-        0x8BDA, "GL_TEXTURE_TARGET_QCOM",
+        0x8BDA,
+        "GL_TEXTURE_TARGET_QCOM",
     },
     {
-        0x8BDB, "GL_TEXTURE_OBJECT_VALID_QCOM",
+        0x8BDB,
+        "GL_TEXTURE_OBJECT_VALID_QCOM",
     },
     {
-        0x8BDC, "GL_STATE_RESTORE",
+        0x8BDC,
+        "GL_STATE_RESTORE",
     },
     {
-        0x8BE7, "GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT",
+        0x8BE7,
+        "GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT",
     },
     {
-        0x8BFA, "GL_TEXTURE_PROTECTED_EXT",
+        0x8BFA,
+        "GL_TEXTURE_PROTECTED_EXT",
     },
     {
-        0x8BFB, "GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM",
+        0x8BFB,
+        "GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM",
     },
     {
-        0x8BFC, "GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM",
+        0x8BFC,
+        "GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM",
     },
     {
-        0x8BFD, "GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM",
+        0x8BFD,
+        "GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM",
     },
     {
-        0x8BFE, "GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM",
+        0x8BFE,
+        "GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM",
     },
     {
-        0x8BFF, "GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM",
+        0x8BFF,
+        "GL_FRAMEBUFFER_INCOMPLETE_FOVEATION_QCOM",
     },
     {
-        0x8C00, "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG",
+        0x8C00,
+        "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG",
     },
     {
-        0x8C01, "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG",
+        0x8C01,
+        "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG",
     },
     {
-        0x8C02, "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",
+        0x8C02,
+        "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG",
     },
     {
-        0x8C03, "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",
+        0x8C03,
+        "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG",
     },
     {
-        0x8C0A, "GL_SGX_BINARY_IMG",
+        0x8C0A,
+        "GL_SGX_BINARY_IMG",
     },
     {
-        0x8C10, "GL_TEXTURE_RED_TYPE",
+        0x8C10,
+        "GL_TEXTURE_RED_TYPE",
     },
     {
-        0x8C11, "GL_TEXTURE_GREEN_TYPE",
+        0x8C11,
+        "GL_TEXTURE_GREEN_TYPE",
     },
     {
-        0x8C12, "GL_TEXTURE_BLUE_TYPE",
+        0x8C12,
+        "GL_TEXTURE_BLUE_TYPE",
     },
     {
-        0x8C13, "GL_TEXTURE_ALPHA_TYPE",
+        0x8C13,
+        "GL_TEXTURE_ALPHA_TYPE",
     },
     {
-        0x8C16, "GL_TEXTURE_DEPTH_TYPE",
+        0x8C16,
+        "GL_TEXTURE_DEPTH_TYPE",
     },
     {
-        0x8C17, "GL_UNSIGNED_NORMALIZED_EXT",
+        0x8C17,
+        "GL_UNSIGNED_NORMALIZED_EXT",
     },
     {
-        0x8C1A, "GL_TEXTURE_2D_ARRAY",
+        0x8C1A,
+        "GL_TEXTURE_2D_ARRAY",
     },
     {
-        0x8C1D, "GL_TEXTURE_BINDING_2D_ARRAY",
+        0x8C1D,
+        "GL_TEXTURE_BINDING_2D_ARRAY",
     },
     {
-        0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES",
+        0x8C29,
+        "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_OES",
     },
     {
-        0x8C2A, "GL_TEXTURE_BUFFER_OES",
+        0x8C2A,
+        "GL_TEXTURE_BUFFER_OES",
     },
     {
-        0x8C2B, "GL_MAX_TEXTURE_BUFFER_SIZE_OES",
+        0x8C2B,
+        "GL_MAX_TEXTURE_BUFFER_SIZE_OES",
     },
     {
-        0x8C2C, "GL_TEXTURE_BINDING_BUFFER_OES",
+        0x8C2C,
+        "GL_TEXTURE_BINDING_BUFFER_OES",
     },
     {
-        0x8C2D, "GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES",
+        0x8C2D,
+        "GL_TEXTURE_BUFFER_DATA_STORE_BINDING_OES",
     },
     {
-        0x8C2F, "GL_ANY_SAMPLES_PASSED_EXT",
+        0x8C2F,
+        "GL_ANY_SAMPLES_PASSED_EXT",
     },
     {
-        0x8C36, "GL_SAMPLE_SHADING_OES",
+        0x8C36,
+        "GL_SAMPLE_SHADING_OES",
     },
     {
-        0x8C37, "GL_MIN_SAMPLE_SHADING_VALUE_OES",
+        0x8C37,
+        "GL_MIN_SAMPLE_SHADING_VALUE_OES",
     },
     {
-        0x8C3A, "GL_R11F_G11F_B10F_APPLE",
+        0x8C3A,
+        "GL_R11F_G11F_B10F_APPLE",
     },
     {
-        0x8C3B, "GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE",
+        0x8C3B,
+        "GL_UNSIGNED_INT_10F_11F_11F_REV_APPLE",
     },
     {
-        0x8C3D, "GL_RGB9_E5_APPLE",
+        0x8C3D,
+        "GL_RGB9_E5_APPLE",
     },
     {
-        0x8C3E, "GL_UNSIGNED_INT_5_9_9_9_REV_APPLE",
+        0x8C3E,
+        "GL_UNSIGNED_INT_5_9_9_9_REV_APPLE",
     },
     {
-        0x8C3F, "GL_TEXTURE_SHARED_SIZE",
+        0x8C3F,
+        "GL_TEXTURE_SHARED_SIZE",
     },
     {
-        0x8C40, "GL_SRGB_EXT",
+        0x8C40,
+        "GL_SRGB_EXT",
     },
     {
-        0x8C41, "GL_SRGB8_NV",
+        0x8C41,
+        "GL_SRGB8_NV",
     },
     {
-        0x8C42, "GL_SRGB_ALPHA_EXT",
+        0x8C42,
+        "GL_SRGB_ALPHA_EXT",
     },
     {
-        0x8C43, "GL_SRGB8_ALPHA8_EXT",
+        0x8C43,
+        "GL_SRGB8_ALPHA8_EXT",
     },
     {
-        0x8C44, "GL_SLUMINANCE_ALPHA_NV",
+        0x8C44,
+        "GL_SLUMINANCE_ALPHA_NV",
     },
     {
-        0x8C45, "GL_SLUMINANCE8_ALPHA8_NV",
+        0x8C45,
+        "GL_SLUMINANCE8_ALPHA8_NV",
     },
     {
-        0x8C46, "GL_SLUMINANCE_NV",
+        0x8C46,
+        "GL_SLUMINANCE_NV",
     },
     {
-        0x8C47, "GL_SLUMINANCE8_NV",
+        0x8C47,
+        "GL_SLUMINANCE8_NV",
     },
     {
-        0x8C4C, "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT",
+        0x8C4C,
+        "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT",
     },
     {
-        0x8C4D, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT",
+        0x8C4D,
+        "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT",
     },
     {
-        0x8C4E, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT",
+        0x8C4E,
+        "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT",
     },
     {
-        0x8C4F, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT",
+        0x8C4F,
+        "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT",
     },
     {
-        0x8C76, "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH",
+        0x8C76,
+        "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH",
     },
     {
-        0x8C7F, "GL_TRANSFORM_FEEDBACK_BUFFER_MODE",
+        0x8C7F,
+        "GL_TRANSFORM_FEEDBACK_BUFFER_MODE",
     },
     {
-        0x8C80, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
+        0x8C80,
+        "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS",
     },
     {
-        0x8C83, "GL_TRANSFORM_FEEDBACK_VARYINGS",
+        0x8C83,
+        "GL_TRANSFORM_FEEDBACK_VARYINGS",
     },
     {
-        0x8C84, "GL_TRANSFORM_FEEDBACK_BUFFER_START",
+        0x8C84,
+        "GL_TRANSFORM_FEEDBACK_BUFFER_START",
     },
     {
-        0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE",
+        0x8C85,
+        "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE",
     },
     {
-        0x8C87, "GL_PRIMITIVES_GENERATED_OES",
+        0x8C87,
+        "GL_PRIMITIVES_GENERATED_OES",
     },
     {
-        0x8C88, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
+        0x8C88,
+        "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN",
     },
     {
-        0x8C89, "GL_RASTERIZER_DISCARD",
+        0x8C89,
+        "GL_RASTERIZER_DISCARD",
     },
     {
-        0x8C8A, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
+        0x8C8A,
+        "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS",
     },
     {
-        0x8C8B, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
+        0x8C8B,
+        "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS",
     },
     {
-        0x8C8C, "GL_INTERLEAVED_ATTRIBS",
+        0x8C8C,
+        "GL_INTERLEAVED_ATTRIBS",
     },
     {
-        0x8C8D, "GL_SEPARATE_ATTRIBS",
+        0x8C8D,
+        "GL_SEPARATE_ATTRIBS",
     },
     {
-        0x8C8E, "GL_TRANSFORM_FEEDBACK_BUFFER",
+        0x8C8E,
+        "GL_TRANSFORM_FEEDBACK_BUFFER",
     },
     {
-        0x8C8F, "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING",
+        0x8C8F,
+        "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING",
     },
     {
-        0x8C92, "GL_ATC_RGB_AMD",
+        0x8C92,
+        "GL_ATC_RGB_AMD",
     },
     {
-        0x8C93, "GL_ATC_RGBA_EXPLICIT_ALPHA_AMD",
+        0x8C93,
+        "GL_ATC_RGBA_EXPLICIT_ALPHA_AMD",
     },
     {
-        0x8CA1, "GL_LOWER_LEFT_EXT",
+        0x8CA1,
+        "GL_LOWER_LEFT_EXT",
     },
     {
-        0x8CA2, "GL_UPPER_LEFT_EXT",
+        0x8CA2,
+        "GL_UPPER_LEFT_EXT",
     },
     {
-        0x8CA3, "GL_STENCIL_BACK_REF",
+        0x8CA3,
+        "GL_STENCIL_BACK_REF",
     },
     {
-        0x8CA4, "GL_STENCIL_BACK_VALUE_MASK",
+        0x8CA4,
+        "GL_STENCIL_BACK_VALUE_MASK",
     },
     {
-        0x8CA5, "GL_STENCIL_BACK_WRITEMASK",
+        0x8CA5,
+        "GL_STENCIL_BACK_WRITEMASK",
     },
     {
-        0x8CA6, "GL_FRAMEBUFFER_BINDING",
+        0x8CA6,
+        "GL_FRAMEBUFFER_BINDING",
     },
     {
-        0x8CA7, "GL_RENDERBUFFER_BINDING",
+        0x8CA7,
+        "GL_RENDERBUFFER_BINDING",
     },
     {
-        0x8CA8, "GL_READ_FRAMEBUFFER_ANGLE",
+        0x8CA8,
+        "GL_READ_FRAMEBUFFER_ANGLE",
     },
     {
-        0x8CA9, "GL_DRAW_FRAMEBUFFER_ANGLE",
+        0x8CA9,
+        "GL_DRAW_FRAMEBUFFER_ANGLE",
     },
     {
-        0x8CAA, "GL_READ_FRAMEBUFFER_BINDING_ANGLE",
+        0x8CAA,
+        "GL_READ_FRAMEBUFFER_BINDING_ANGLE",
     },
     {
-        0x8CAB, "GL_RENDERBUFFER_SAMPLES_ANGLE",
+        0x8CAB,
+        "GL_RENDERBUFFER_SAMPLES_ANGLE",
     },
     {
-        0x8CAC, "GL_DEPTH_COMPONENT32F",
+        0x8CAC,
+        "GL_DEPTH_COMPONENT32F",
     },
     {
-        0x8CAD, "GL_DEPTH32F_STENCIL8",
+        0x8CAD,
+        "GL_DEPTH32F_STENCIL8",
     },
     {
-        0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
+        0x8CD0,
+        "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE",
     },
     {
-        0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
+        0x8CD1,
+        "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME",
     },
     {
-        0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
+        0x8CD2,
+        "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL",
     },
     {
-        0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
+        0x8CD3,
+        "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE",
     },
     {
-        0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES",
+        0x8CD4,
+        "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES",
     },
     {
-        0x8CD5, "GL_FRAMEBUFFER_COMPLETE",
+        0x8CD5,
+        "GL_FRAMEBUFFER_COMPLETE",
     },
     {
-        0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
+        0x8CD6,
+        "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
     },
     {
-        0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
+        0x8CD7,
+        "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
     },
     {
-        0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
+        0x8CD9,
+        "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
     },
     {
-        0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED",
+        0x8CDD,
+        "GL_FRAMEBUFFER_UNSUPPORTED",
     },
     {
-        0x8CDF, "GL_MAX_COLOR_ATTACHMENTS_EXT",
+        0x8CDF,
+        "GL_MAX_COLOR_ATTACHMENTS_EXT",
     },
     {
-        0x8CE0, "GL_COLOR_ATTACHMENT0",
+        0x8CE0,
+        "GL_COLOR_ATTACHMENT0",
     },
     {
-        0x8CE1, "GL_COLOR_ATTACHMENT1_EXT",
+        0x8CE1,
+        "GL_COLOR_ATTACHMENT1_EXT",
     },
     {
-        0x8CE2, "GL_COLOR_ATTACHMENT2_EXT",
+        0x8CE2,
+        "GL_COLOR_ATTACHMENT2_EXT",
     },
     {
-        0x8CE3, "GL_COLOR_ATTACHMENT3_EXT",
+        0x8CE3,
+        "GL_COLOR_ATTACHMENT3_EXT",
     },
     {
-        0x8CE4, "GL_COLOR_ATTACHMENT4_EXT",
+        0x8CE4,
+        "GL_COLOR_ATTACHMENT4_EXT",
     },
     {
-        0x8CE5, "GL_COLOR_ATTACHMENT5_EXT",
+        0x8CE5,
+        "GL_COLOR_ATTACHMENT5_EXT",
     },
     {
-        0x8CE6, "GL_COLOR_ATTACHMENT6_EXT",
+        0x8CE6,
+        "GL_COLOR_ATTACHMENT6_EXT",
     },
     {
-        0x8CE7, "GL_COLOR_ATTACHMENT7_EXT",
+        0x8CE7,
+        "GL_COLOR_ATTACHMENT7_EXT",
     },
     {
-        0x8CE8, "GL_COLOR_ATTACHMENT8_EXT",
+        0x8CE8,
+        "GL_COLOR_ATTACHMENT8_EXT",
     },
     {
-        0x8CE9, "GL_COLOR_ATTACHMENT9_EXT",
+        0x8CE9,
+        "GL_COLOR_ATTACHMENT9_EXT",
     },
     {
-        0x8CEA, "GL_COLOR_ATTACHMENT10_EXT",
+        0x8CEA,
+        "GL_COLOR_ATTACHMENT10_EXT",
     },
     {
-        0x8CEB, "GL_COLOR_ATTACHMENT11_EXT",
+        0x8CEB,
+        "GL_COLOR_ATTACHMENT11_EXT",
     },
     {
-        0x8CEC, "GL_COLOR_ATTACHMENT12_EXT",
+        0x8CEC,
+        "GL_COLOR_ATTACHMENT12_EXT",
     },
     {
-        0x8CED, "GL_COLOR_ATTACHMENT13_EXT",
+        0x8CED,
+        "GL_COLOR_ATTACHMENT13_EXT",
     },
     {
-        0x8CEE, "GL_COLOR_ATTACHMENT14_EXT",
+        0x8CEE,
+        "GL_COLOR_ATTACHMENT14_EXT",
     },
     {
-        0x8CEF, "GL_COLOR_ATTACHMENT15_EXT",
+        0x8CEF,
+        "GL_COLOR_ATTACHMENT15_EXT",
     },
     {
-        0x8CF0, "GL_COLOR_ATTACHMENT16",
+        0x8CF0,
+        "GL_COLOR_ATTACHMENT16",
     },
     {
-        0x8CF1, "GL_COLOR_ATTACHMENT17",
+        0x8CF1,
+        "GL_COLOR_ATTACHMENT17",
     },
     {
-        0x8CF2, "GL_COLOR_ATTACHMENT18",
+        0x8CF2,
+        "GL_COLOR_ATTACHMENT18",
     },
     {
-        0x8CF3, "GL_COLOR_ATTACHMENT19",
+        0x8CF3,
+        "GL_COLOR_ATTACHMENT19",
     },
     {
-        0x8CF4, "GL_COLOR_ATTACHMENT20",
+        0x8CF4,
+        "GL_COLOR_ATTACHMENT20",
     },
     {
-        0x8CF5, "GL_COLOR_ATTACHMENT21",
+        0x8CF5,
+        "GL_COLOR_ATTACHMENT21",
     },
     {
-        0x8CF6, "GL_COLOR_ATTACHMENT22",
+        0x8CF6,
+        "GL_COLOR_ATTACHMENT22",
     },
     {
-        0x8CF7, "GL_COLOR_ATTACHMENT23",
+        0x8CF7,
+        "GL_COLOR_ATTACHMENT23",
     },
     {
-        0x8CF8, "GL_COLOR_ATTACHMENT24",
+        0x8CF8,
+        "GL_COLOR_ATTACHMENT24",
     },
     {
-        0x8CF9, "GL_COLOR_ATTACHMENT25",
+        0x8CF9,
+        "GL_COLOR_ATTACHMENT25",
     },
     {
-        0x8CFA, "GL_COLOR_ATTACHMENT26",
+        0x8CFA,
+        "GL_COLOR_ATTACHMENT26",
     },
     {
-        0x8CFB, "GL_COLOR_ATTACHMENT27",
+        0x8CFB,
+        "GL_COLOR_ATTACHMENT27",
     },
     {
-        0x8CFC, "GL_COLOR_ATTACHMENT28",
+        0x8CFC,
+        "GL_COLOR_ATTACHMENT28",
     },
     {
-        0x8CFD, "GL_COLOR_ATTACHMENT29",
+        0x8CFD,
+        "GL_COLOR_ATTACHMENT29",
     },
     {
-        0x8CFE, "GL_COLOR_ATTACHMENT30",
+        0x8CFE,
+        "GL_COLOR_ATTACHMENT30",
     },
     {
-        0x8CFF, "GL_COLOR_ATTACHMENT31",
+        0x8CFF,
+        "GL_COLOR_ATTACHMENT31",
     },
     {
-        0x8D00, "GL_DEPTH_ATTACHMENT",
+        0x8D00,
+        "GL_DEPTH_ATTACHMENT",
     },
     {
-        0x8D20, "GL_STENCIL_ATTACHMENT",
+        0x8D20,
+        "GL_STENCIL_ATTACHMENT",
     },
     {
-        0x8D40, "GL_FRAMEBUFFER",
+        0x8D40,
+        "GL_FRAMEBUFFER",
     },
     {
-        0x8D41, "GL_RENDERBUFFER",
+        0x8D41,
+        "GL_RENDERBUFFER",
     },
     {
-        0x8D42, "GL_RENDERBUFFER_WIDTH",
+        0x8D42,
+        "GL_RENDERBUFFER_WIDTH",
     },
     {
-        0x8D43, "GL_RENDERBUFFER_HEIGHT",
+        0x8D43,
+        "GL_RENDERBUFFER_HEIGHT",
     },
     {
-        0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT",
+        0x8D44,
+        "GL_RENDERBUFFER_INTERNAL_FORMAT",
     },
     {
-        0x8D46, "GL_STENCIL_INDEX1_OES",
+        0x8D46,
+        "GL_STENCIL_INDEX1_OES",
     },
     {
-        0x8D47, "GL_STENCIL_INDEX4_OES",
+        0x8D47,
+        "GL_STENCIL_INDEX4_OES",
     },
     {
-        0x8D48, "GL_STENCIL_INDEX8",
+        0x8D48,
+        "GL_STENCIL_INDEX8",
     },
     {
-        0x8D50, "GL_RENDERBUFFER_RED_SIZE",
+        0x8D50,
+        "GL_RENDERBUFFER_RED_SIZE",
     },
     {
-        0x8D51, "GL_RENDERBUFFER_GREEN_SIZE",
+        0x8D51,
+        "GL_RENDERBUFFER_GREEN_SIZE",
     },
     {
-        0x8D52, "GL_RENDERBUFFER_BLUE_SIZE",
+        0x8D52,
+        "GL_RENDERBUFFER_BLUE_SIZE",
     },
     {
-        0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE",
+        0x8D53,
+        "GL_RENDERBUFFER_ALPHA_SIZE",
     },
     {
-        0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE",
+        0x8D54,
+        "GL_RENDERBUFFER_DEPTH_SIZE",
     },
     {
-        0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE",
+        0x8D55,
+        "GL_RENDERBUFFER_STENCIL_SIZE",
     },
     {
-        0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE",
+        0x8D56,
+        "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE",
     },
     {
-        0x8D57, "GL_MAX_SAMPLES_ANGLE",
+        0x8D57,
+        "GL_MAX_SAMPLES_ANGLE",
     },
     {
-        0x8D61, "GL_HALF_FLOAT_OES",
+        0x8D61,
+        "GL_HALF_FLOAT_OES",
     },
     {
-        0x8D62, "GL_RGB565",
+        0x8D62,
+        "GL_RGB565",
     },
     {
-        0x8D64, "GL_ETC1_RGB8_OES",
+        0x8D64,
+        "GL_ETC1_RGB8_OES",
     },
     {
-        0x8D65, "GL_TEXTURE_EXTERNAL_OES",
+        0x8D65,
+        "GL_TEXTURE_EXTERNAL_OES",
     },
     {
-        0x8D66, "GL_SAMPLER_EXTERNAL_OES",
+        0x8D66,
+        "GL_SAMPLER_EXTERNAL_OES",
     },
     {
-        0x8D67, "GL_TEXTURE_BINDING_EXTERNAL_OES",
+        0x8D67,
+        "GL_TEXTURE_BINDING_EXTERNAL_OES",
     },
     {
-        0x8D68, "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES",
+        0x8D68,
+        "GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES",
     },
     {
-        0x8D69, "GL_PRIMITIVE_RESTART_FIXED_INDEX",
+        0x8D69,
+        "GL_PRIMITIVE_RESTART_FIXED_INDEX",
     },
     {
-        0x8D6A, "GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT",
+        0x8D6A,
+        "GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT",
     },
     {
-        0x8D6B, "GL_MAX_ELEMENT_INDEX",
+        0x8D6B,
+        "GL_MAX_ELEMENT_INDEX",
     },
     {
-        0x8D6C, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT",
+        0x8D6C,
+        "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT",
     },
     {
-        0x8D70, "GL_RGBA32UI",
+        0x8D70,
+        "GL_RGBA32UI",
     },
     {
-        0x8D71, "GL_RGB32UI",
+        0x8D71,
+        "GL_RGB32UI",
     },
     {
-        0x8D76, "GL_RGBA16UI",
+        0x8D76,
+        "GL_RGBA16UI",
     },
     {
-        0x8D77, "GL_RGB16UI",
+        0x8D77,
+        "GL_RGB16UI",
     },
     {
-        0x8D7C, "GL_RGBA8UI",
+        0x8D7C,
+        "GL_RGBA8UI",
     },
     {
-        0x8D7D, "GL_RGB8UI",
+        0x8D7D,
+        "GL_RGB8UI",
     },
     {
-        0x8D82, "GL_RGBA32I",
+        0x8D82,
+        "GL_RGBA32I",
     },
     {
-        0x8D83, "GL_RGB32I",
+        0x8D83,
+        "GL_RGB32I",
     },
     {
-        0x8D88, "GL_RGBA16I",
+        0x8D88,
+        "GL_RGBA16I",
     },
     {
-        0x8D89, "GL_RGB16I",
+        0x8D89,
+        "GL_RGB16I",
     },
     {
-        0x8D8E, "GL_RGBA8I",
+        0x8D8E,
+        "GL_RGBA8I",
     },
     {
-        0x8D8F, "GL_RGB8I",
+        0x8D8F,
+        "GL_RGB8I",
     },
     {
-        0x8D94, "GL_RED_INTEGER",
+        0x8D94,
+        "GL_RED_INTEGER",
     },
     {
-        0x8D98, "GL_RGB_INTEGER",
+        0x8D98,
+        "GL_RGB_INTEGER",
     },
     {
-        0x8D99, "GL_RGBA_INTEGER",
+        0x8D99,
+        "GL_RGBA_INTEGER",
     },
     {
-        0x8D9F, "GL_INT_2_10_10_10_REV",
+        0x8D9F,
+        "GL_INT_2_10_10_10_REV",
     },
     {
-        0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES",
+        0x8DA7,
+        "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_OES",
     },
     {
-        0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES",
+        0x8DA8,
+        "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_OES",
     },
     {
-        0x8DAD, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV",
+        0x8DAD,
+        "GL_FLOAT_32_UNSIGNED_INT_24_8_REV",
     },
     {
-        0x8DB9, "GL_FRAMEBUFFER_SRGB_EXT",
+        0x8DB9,
+        "GL_FRAMEBUFFER_SRGB_EXT",
     },
     {
-        0x8DBB, "GL_COMPRESSED_RED_RGTC1_EXT",
+        0x8DBB,
+        "GL_COMPRESSED_RED_RGTC1_EXT",
     },
     {
-        0x8DBC, "GL_COMPRESSED_SIGNED_RED_RGTC1_EXT",
+        0x8DBC,
+        "GL_COMPRESSED_SIGNED_RED_RGTC1_EXT",
     },
     {
-        0x8DBD, "GL_COMPRESSED_RED_GREEN_RGTC2_EXT",
+        0x8DBD,
+        "GL_COMPRESSED_RED_GREEN_RGTC2_EXT",
     },
     {
-        0x8DBE, "GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT",
+        0x8DBE,
+        "GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT",
     },
     {
-        0x8DC1, "GL_SAMPLER_2D_ARRAY",
+        0x8DC1,
+        "GL_SAMPLER_2D_ARRAY",
     },
     {
-        0x8DC2, "GL_SAMPLER_BUFFER_OES",
+        0x8DC2,
+        "GL_SAMPLER_BUFFER_OES",
     },
     {
-        0x8DC4, "GL_SAMPLER_2D_ARRAY_SHADOW_NV",
+        0x8DC4,
+        "GL_SAMPLER_2D_ARRAY_SHADOW_NV",
     },
     {
-        0x8DC5, "GL_SAMPLER_CUBE_SHADOW_NV",
+        0x8DC5,
+        "GL_SAMPLER_CUBE_SHADOW_NV",
     },
     {
-        0x8DC6, "GL_UNSIGNED_INT_VEC2",
+        0x8DC6,
+        "GL_UNSIGNED_INT_VEC2",
     },
     {
-        0x8DC7, "GL_UNSIGNED_INT_VEC3",
+        0x8DC7,
+        "GL_UNSIGNED_INT_VEC3",
     },
     {
-        0x8DC8, "GL_UNSIGNED_INT_VEC4",
+        0x8DC8,
+        "GL_UNSIGNED_INT_VEC4",
     },
     {
-        0x8DCA, "GL_INT_SAMPLER_2D",
+        0x8DCA,
+        "GL_INT_SAMPLER_2D",
     },
     {
-        0x8DCB, "GL_INT_SAMPLER_3D",
+        0x8DCB,
+        "GL_INT_SAMPLER_3D",
     },
     {
-        0x8DCC, "GL_INT_SAMPLER_CUBE",
+        0x8DCC,
+        "GL_INT_SAMPLER_CUBE",
     },
     {
-        0x8DCF, "GL_INT_SAMPLER_2D_ARRAY",
+        0x8DCF,
+        "GL_INT_SAMPLER_2D_ARRAY",
     },
     {
-        0x8DD0, "GL_INT_SAMPLER_BUFFER_OES",
+        0x8DD0,
+        "GL_INT_SAMPLER_BUFFER_OES",
     },
     {
-        0x8DD2, "GL_UNSIGNED_INT_SAMPLER_2D",
+        0x8DD2,
+        "GL_UNSIGNED_INT_SAMPLER_2D",
     },
     {
-        0x8DD3, "GL_UNSIGNED_INT_SAMPLER_3D",
+        0x8DD3,
+        "GL_UNSIGNED_INT_SAMPLER_3D",
     },
     {
-        0x8DD4, "GL_UNSIGNED_INT_SAMPLER_CUBE",
+        0x8DD4,
+        "GL_UNSIGNED_INT_SAMPLER_CUBE",
     },
     {
-        0x8DD7, "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY",
+        0x8DD7,
+        "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY",
     },
     {
-        0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER_OES",
+        0x8DD8,
+        "GL_UNSIGNED_INT_SAMPLER_BUFFER_OES",
     },
     {
-        0x8DD9, "GL_GEOMETRY_SHADER_OES",
+        0x8DD9,
+        "GL_GEOMETRY_SHADER_OES",
     },
     {
-        0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES",
+        0x8DDF,
+        "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_OES",
     },
     {
-        0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES",
+        0x8DE0,
+        "GL_MAX_GEOMETRY_OUTPUT_VERTICES_OES",
     },
     {
-        0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES",
+        0x8DE1,
+        "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_OES",
     },
     {
-        0x8DF0, "GL_LOW_FLOAT",
+        0x8DF0,
+        "GL_LOW_FLOAT",
     },
     {
-        0x8DF1, "GL_MEDIUM_FLOAT",
+        0x8DF1,
+        "GL_MEDIUM_FLOAT",
     },
     {
-        0x8DF2, "GL_HIGH_FLOAT",
+        0x8DF2,
+        "GL_HIGH_FLOAT",
     },
     {
-        0x8DF3, "GL_LOW_INT",
+        0x8DF3,
+        "GL_LOW_INT",
     },
     {
-        0x8DF4, "GL_MEDIUM_INT",
+        0x8DF4,
+        "GL_MEDIUM_INT",
     },
     {
-        0x8DF5, "GL_HIGH_INT",
+        0x8DF5,
+        "GL_HIGH_INT",
     },
     {
-        0x8DF6, "GL_UNSIGNED_INT_10_10_10_2_OES",
+        0x8DF6,
+        "GL_UNSIGNED_INT_10_10_10_2_OES",
     },
     {
-        0x8DF7, "GL_INT_10_10_10_2_OES",
+        0x8DF7,
+        "GL_INT_10_10_10_2_OES",
     },
     {
-        0x8DF8, "GL_SHADER_BINARY_FORMATS",
+        0x8DF8,
+        "GL_SHADER_BINARY_FORMATS",
     },
     {
-        0x8DF9, "GL_NUM_SHADER_BINARY_FORMATS",
+        0x8DF9,
+        "GL_NUM_SHADER_BINARY_FORMATS",
     },
     {
-        0x8DFA, "GL_SHADER_COMPILER",
+        0x8DFA,
+        "GL_SHADER_COMPILER",
     },
     {
-        0x8DFB, "GL_MAX_VERTEX_UNIFORM_VECTORS",
+        0x8DFB,
+        "GL_MAX_VERTEX_UNIFORM_VECTORS",
     },
     {
-        0x8DFC, "GL_MAX_VARYING_VECTORS",
+        0x8DFC,
+        "GL_MAX_VARYING_VECTORS",
     },
     {
-        0x8DFD, "GL_MAX_FRAGMENT_UNIFORM_VECTORS",
+        0x8DFD,
+        "GL_MAX_FRAGMENT_UNIFORM_VECTORS",
     },
     {
-        0x8E13, "GL_QUERY_WAIT_NV",
+        0x8E13,
+        "GL_QUERY_WAIT_NV",
     },
     {
-        0x8E14, "GL_QUERY_NO_WAIT_NV",
+        0x8E14,
+        "GL_QUERY_NO_WAIT_NV",
     },
     {
-        0x8E15, "GL_QUERY_BY_REGION_WAIT_NV",
+        0x8E15,
+        "GL_QUERY_BY_REGION_WAIT_NV",
     },
     {
-        0x8E16, "GL_QUERY_BY_REGION_NO_WAIT_NV",
+        0x8E16,
+        "GL_QUERY_BY_REGION_NO_WAIT_NV",
     },
     {
-        0x8E1B, "GL_POLYGON_OFFSET_CLAMP_EXT",
+        0x8E1B,
+        "GL_POLYGON_OFFSET_CLAMP_EXT",
     },
     {
-        0x8E1E, "GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES",
+        0x8E1E,
+        "GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_OES",
     },
     {
-        0x8E1F, "GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES",
+        0x8E1F,
+        "GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_OES",
     },
     {
-        0x8E20, "GL_COLOR_SAMPLES_NV",
+        0x8E20,
+        "GL_COLOR_SAMPLES_NV",
     },
     {
-        0x8E22, "GL_TRANSFORM_FEEDBACK",
+        0x8E22,
+        "GL_TRANSFORM_FEEDBACK",
     },
     {
-        0x8E23, "GL_TRANSFORM_FEEDBACK_PAUSED",
+        0x8E23,
+        "GL_TRANSFORM_FEEDBACK_PAUSED",
     },
     {
-        0x8E24, "GL_TRANSFORM_FEEDBACK_ACTIVE",
+        0x8E24,
+        "GL_TRANSFORM_FEEDBACK_ACTIVE",
     },
     {
-        0x8E25, "GL_TRANSFORM_FEEDBACK_BINDING",
+        0x8E25,
+        "GL_TRANSFORM_FEEDBACK_BINDING",
     },
     {
-        0x8E28, "GL_TIMESTAMP_EXT",
+        0x8E28,
+        "GL_TIMESTAMP_EXT",
     },
     {
-        0x8E2C, "GL_DEPTH_COMPONENT16_NONLINEAR_NV",
+        0x8E2C,
+        "GL_DEPTH_COMPONENT16_NONLINEAR_NV",
     },
     {
-        0x8E42, "GL_TEXTURE_SWIZZLE_R",
+        0x8E42,
+        "GL_TEXTURE_SWIZZLE_R",
     },
     {
-        0x8E43, "GL_TEXTURE_SWIZZLE_G",
+        0x8E43,
+        "GL_TEXTURE_SWIZZLE_G",
     },
     {
-        0x8E44, "GL_TEXTURE_SWIZZLE_B",
+        0x8E44,
+        "GL_TEXTURE_SWIZZLE_B",
     },
     {
-        0x8E45, "GL_TEXTURE_SWIZZLE_A",
+        0x8E45,
+        "GL_TEXTURE_SWIZZLE_A",
     },
     {
-        0x8E4D, "GL_FIRST_VERTEX_CONVENTION_OES",
+        0x8E4D,
+        "GL_FIRST_VERTEX_CONVENTION_OES",
     },
     {
-        0x8E4E, "GL_LAST_VERTEX_CONVENTION_OES",
+        0x8E4E,
+        "GL_LAST_VERTEX_CONVENTION_OES",
     },
     {
-        0x8E50, "GL_SAMPLE_LOCATION_NV",
+        0x8E50,
+        "GL_SAMPLE_LOCATION_NV",
     },
     {
-        0x8E51, "GL_SAMPLE_MASK",
+        0x8E51,
+        "GL_SAMPLE_MASK",
     },
     {
-        0x8E52, "GL_SAMPLE_MASK_VALUE",
+        0x8E52,
+        "GL_SAMPLE_MASK_VALUE",
     },
     {
-        0x8E59, "GL_MAX_SAMPLE_MASK_WORDS",
+        0x8E59,
+        "GL_MAX_SAMPLE_MASK_WORDS",
     },
     {
-        0x8E5A, "GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES",
+        0x8E5A,
+        "GL_MAX_GEOMETRY_SHADER_INVOCATIONS_OES",
     },
     {
-        0x8E5B, "GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES",
+        0x8E5B,
+        "GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES",
     },
     {
-        0x8E5C, "GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES",
+        0x8E5C,
+        "GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES",
     },
     {
-        0x8E5D, "GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES",
+        0x8E5D,
+        "GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES",
     },
     {
-        0x8E5E, "GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET",
+        0x8E5E,
+        "GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET",
     },
     {
-        0x8E5F, "GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET",
+        0x8E5F,
+        "GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET",
     },
     {
-        0x8E72, "GL_PATCH_VERTICES_OES",
+        0x8E72,
+        "GL_PATCH_VERTICES_OES",
     },
     {
-        0x8E75, "GL_TESS_CONTROL_OUTPUT_VERTICES_OES",
+        0x8E75,
+        "GL_TESS_CONTROL_OUTPUT_VERTICES_OES",
     },
     {
-        0x8E76, "GL_TESS_GEN_MODE_OES",
+        0x8E76,
+        "GL_TESS_GEN_MODE_OES",
     },
     {
-        0x8E77, "GL_TESS_GEN_SPACING_OES",
+        0x8E77,
+        "GL_TESS_GEN_SPACING_OES",
     },
     {
-        0x8E78, "GL_TESS_GEN_VERTEX_ORDER_OES",
+        0x8E78,
+        "GL_TESS_GEN_VERTEX_ORDER_OES",
     },
     {
-        0x8E79, "GL_TESS_GEN_POINT_MODE_OES",
+        0x8E79,
+        "GL_TESS_GEN_POINT_MODE_OES",
     },
     {
-        0x8E7A, "GL_ISOLINES_OES",
+        0x8E7A,
+        "GL_ISOLINES_OES",
     },
     {
-        0x8E7B, "GL_FRACTIONAL_ODD_OES",
+        0x8E7B,
+        "GL_FRACTIONAL_ODD_OES",
     },
     {
-        0x8E7C, "GL_FRACTIONAL_EVEN_OES",
+        0x8E7C,
+        "GL_FRACTIONAL_EVEN_OES",
     },
     {
-        0x8E7D, "GL_MAX_PATCH_VERTICES_OES",
+        0x8E7D,
+        "GL_MAX_PATCH_VERTICES_OES",
     },
     {
-        0x8E7E, "GL_MAX_TESS_GEN_LEVEL_OES",
+        0x8E7E,
+        "GL_MAX_TESS_GEN_LEVEL_OES",
     },
     {
-        0x8E7F, "GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES",
+        0x8E7F,
+        "GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_OES",
     },
     {
-        0x8E80, "GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES",
+        0x8E80,
+        "GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_OES",
     },
     {
-        0x8E81, "GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES",
+        0x8E81,
+        "GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_OES",
     },
     {
-        0x8E82, "GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES",
+        0x8E82,
+        "GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_OES",
     },
     {
-        0x8E83, "GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES",
+        0x8E83,
+        "GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_OES",
     },
     {
-        0x8E84, "GL_MAX_TESS_PATCH_COMPONENTS_OES",
+        0x8E84,
+        "GL_MAX_TESS_PATCH_COMPONENTS_OES",
     },
     {
-        0x8E85, "GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES",
+        0x8E85,
+        "GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_OES",
     },
     {
-        0x8E86, "GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES",
+        0x8E86,
+        "GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_OES",
     },
     {
-        0x8E87, "GL_TESS_EVALUATION_SHADER_OES",
+        0x8E87,
+        "GL_TESS_EVALUATION_SHADER_OES",
     },
     {
-        0x8E88, "GL_TESS_CONTROL_SHADER_OES",
+        0x8E88,
+        "GL_TESS_CONTROL_SHADER_OES",
     },
     {
-        0x8E89, "GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES",
+        0x8E89,
+        "GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_OES",
     },
     {
-        0x8E8A, "GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES",
+        0x8E8A,
+        "GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_OES",
     },
     {
-        0x8E8C, "GL_COMPRESSED_RGBA_BPTC_UNORM_EXT",
+        0x8E8C,
+        "GL_COMPRESSED_RGBA_BPTC_UNORM_EXT",
     },
     {
-        0x8E8D, "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT",
+        0x8E8D,
+        "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT",
     },
     {
-        0x8E8E, "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT",
+        0x8E8E,
+        "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT",
     },
     {
-        0x8E8F, "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT",
+        0x8E8F,
+        "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT",
     },
     {
-        0x8ED0, "GL_COVERAGE_COMPONENT_NV",
+        0x8ED0,
+        "GL_COVERAGE_COMPONENT_NV",
     },
     {
-        0x8ED1, "GL_COVERAGE_COMPONENT4_NV",
+        0x8ED1,
+        "GL_COVERAGE_COMPONENT4_NV",
     },
     {
-        0x8ED2, "GL_COVERAGE_ATTACHMENT_NV",
+        0x8ED2,
+        "GL_COVERAGE_ATTACHMENT_NV",
     },
     {
-        0x8ED3, "GL_COVERAGE_BUFFERS_NV",
+        0x8ED3,
+        "GL_COVERAGE_BUFFERS_NV",
     },
     {
-        0x8ED4, "GL_COVERAGE_SAMPLES_NV",
+        0x8ED4,
+        "GL_COVERAGE_SAMPLES_NV",
     },
     {
-        0x8ED5, "GL_COVERAGE_ALL_FRAGMENTS_NV",
+        0x8ED5,
+        "GL_COVERAGE_ALL_FRAGMENTS_NV",
     },
     {
-        0x8ED6, "GL_COVERAGE_EDGE_FRAGMENTS_NV",
+        0x8ED6,
+        "GL_COVERAGE_EDGE_FRAGMENTS_NV",
     },
     {
-        0x8ED7, "GL_COVERAGE_AUTOMATIC_NV",
+        0x8ED7,
+        "GL_COVERAGE_AUTOMATIC_NV",
     },
     {
-        0x8F10, "GL_INCLUSIVE_EXT",
+        0x8F10,
+        "GL_INCLUSIVE_EXT",
     },
     {
-        0x8F11, "GL_EXCLUSIVE_EXT",
+        0x8F11,
+        "GL_EXCLUSIVE_EXT",
     },
     {
-        0x8F12, "GL_WINDOW_RECTANGLE_EXT",
+        0x8F12,
+        "GL_WINDOW_RECTANGLE_EXT",
     },
     {
-        0x8F13, "GL_WINDOW_RECTANGLE_MODE_EXT",
+        0x8F13,
+        "GL_WINDOW_RECTANGLE_MODE_EXT",
     },
     {
-        0x8F14, "GL_MAX_WINDOW_RECTANGLES_EXT",
+        0x8F14,
+        "GL_MAX_WINDOW_RECTANGLES_EXT",
     },
     {
-        0x8F15, "GL_NUM_WINDOW_RECTANGLES_EXT",
+        0x8F15,
+        "GL_NUM_WINDOW_RECTANGLES_EXT",
     },
     {
-        0x8F36, "GL_COPY_READ_BUFFER_NV",
+        0x8F36,
+        "GL_COPY_READ_BUFFER_NV",
     },
     {
-        0x8F37, "GL_COPY_WRITE_BUFFER_NV",
+        0x8F37,
+        "GL_COPY_WRITE_BUFFER_NV",
     },
     {
-        0x8F38, "GL_MAX_IMAGE_UNITS",
+        0x8F38,
+        "GL_MAX_IMAGE_UNITS",
     },
     {
-        0x8F39, "GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES",
+        0x8F39,
+        "GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES",
     },
     {
-        0x8F3A, "GL_IMAGE_BINDING_NAME",
+        0x8F3A,
+        "GL_IMAGE_BINDING_NAME",
     },
     {
-        0x8F3B, "GL_IMAGE_BINDING_LEVEL",
+        0x8F3B,
+        "GL_IMAGE_BINDING_LEVEL",
     },
     {
-        0x8F3C, "GL_IMAGE_BINDING_LAYERED",
+        0x8F3C,
+        "GL_IMAGE_BINDING_LAYERED",
     },
     {
-        0x8F3D, "GL_IMAGE_BINDING_LAYER",
+        0x8F3D,
+        "GL_IMAGE_BINDING_LAYER",
     },
     {
-        0x8F3E, "GL_IMAGE_BINDING_ACCESS",
+        0x8F3E,
+        "GL_IMAGE_BINDING_ACCESS",
     },
     {
-        0x8F3F, "GL_DRAW_INDIRECT_BUFFER",
+        0x8F3F,
+        "GL_DRAW_INDIRECT_BUFFER",
     },
     {
-        0x8F43, "GL_DRAW_INDIRECT_BUFFER_BINDING",
+        0x8F43,
+        "GL_DRAW_INDIRECT_BUFFER_BINDING",
     },
     {
-        0x8F4F, "GL_VERTEX_BINDING_BUFFER",
+        0x8F4F,
+        "GL_VERTEX_BINDING_BUFFER",
     },
     {
-        0x8F60, "GL_MALI_SHADER_BINARY_ARM",
+        0x8F60,
+        "GL_MALI_SHADER_BINARY_ARM",
     },
     {
-        0x8F61, "GL_MALI_PROGRAM_BINARY_ARM",
+        0x8F61,
+        "GL_MALI_PROGRAM_BINARY_ARM",
     },
     {
-        0x8F63, "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT",
+        0x8F63,
+        "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_FAST_SIZE_EXT",
     },
     {
-        0x8F64, "GL_SHADER_PIXEL_LOCAL_STORAGE_EXT",
+        0x8F64,
+        "GL_SHADER_PIXEL_LOCAL_STORAGE_EXT",
     },
     {
-        0x8F65, "GL_FETCH_PER_SAMPLE_ARM",
+        0x8F65,
+        "GL_FETCH_PER_SAMPLE_ARM",
     },
     {
-        0x8F66, "GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM",
+        0x8F66,
+        "GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM",
     },
     {
-        0x8F67, "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT",
+        0x8F67,
+        "GL_MAX_SHADER_PIXEL_LOCAL_STORAGE_SIZE_EXT",
     },
     {
-        0x8F69, "GL_TEXTURE_ASTC_DECODE_PRECISION_EXT",
+        0x8F69,
+        "GL_TEXTURE_ASTC_DECODE_PRECISION_EXT",
     },
     {
-        0x8F94, "GL_R8_SNORM",
+        0x8F94,
+        "GL_R8_SNORM",
     },
     {
-        0x8F95, "GL_RG8_SNORM",
+        0x8F95,
+        "GL_RG8_SNORM",
     },
     {
-        0x8F96, "GL_RGB8_SNORM",
+        0x8F96,
+        "GL_RGB8_SNORM",
     },
     {
-        0x8F97, "GL_RGBA8_SNORM",
+        0x8F97,
+        "GL_RGBA8_SNORM",
     },
     {
-        0x8F98, "GL_R16_SNORM_EXT",
+        0x8F98,
+        "GL_R16_SNORM_EXT",
     },
     {
-        0x8F99, "GL_RG16_SNORM_EXT",
+        0x8F99,
+        "GL_RG16_SNORM_EXT",
     },
     {
-        0x8F9A, "GL_RGB16_SNORM_EXT",
+        0x8F9A,
+        "GL_RGB16_SNORM_EXT",
     },
     {
-        0x8F9B, "GL_RGBA16_SNORM_EXT",
+        0x8F9B,
+        "GL_RGBA16_SNORM_EXT",
     },
     {
-        0x8F9C, "GL_SIGNED_NORMALIZED",
+        0x8F9C,
+        "GL_SIGNED_NORMALIZED",
     },
     {
-        0x8FA0, "GL_PERFMON_GLOBAL_MODE_QCOM",
+        0x8FA0,
+        "GL_PERFMON_GLOBAL_MODE_QCOM",
     },
     {
-        0x8FB0, "GL_BINNING_CONTROL_HINT_QCOM",
+        0x8FB0,
+        "GL_BINNING_CONTROL_HINT_QCOM",
     },
     {
-        0x8FB1, "GL_CPU_OPTIMIZED_QCOM",
+        0x8FB1,
+        "GL_CPU_OPTIMIZED_QCOM",
     },
     {
-        0x8FB2, "GL_GPU_OPTIMIZED_QCOM",
+        0x8FB2,
+        "GL_GPU_OPTIMIZED_QCOM",
     },
     {
-        0x8FB3, "GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM",
+        0x8FB3,
+        "GL_RENDER_DIRECT_TO_FRAMEBUFFER_QCOM",
     },
     {
-        0x8FBB, "GL_GPU_DISJOINT_EXT",
+        0x8FBB,
+        "GL_GPU_DISJOINT_EXT",
     },
     {
-        0x8FBD, "GL_SR8_EXT",
+        0x8FBD,
+        "GL_SR8_EXT",
     },
     {
-        0x8FBE, "GL_SRG8_EXT",
+        0x8FBE,
+        "GL_SRG8_EXT",
     },
     {
-        0x8FBF, "GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT",
+        0x8FBF,
+        "GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT",
     },
     {
-        0x8FC4, "GL_SHADER_BINARY_VIV",
+        0x8FC4,
+        "GL_SHADER_BINARY_VIV",
     },
     {
-        0x8FE0, "GL_INT8_NV",
+        0x8FE0,
+        "GL_INT8_NV",
     },
     {
-        0x8FE1, "GL_INT8_VEC2_NV",
+        0x8FE1,
+        "GL_INT8_VEC2_NV",
     },
     {
-        0x8FE2, "GL_INT8_VEC3_NV",
+        0x8FE2,
+        "GL_INT8_VEC3_NV",
     },
     {
-        0x8FE3, "GL_INT8_VEC4_NV",
+        0x8FE3,
+        "GL_INT8_VEC4_NV",
     },
     {
-        0x8FE4, "GL_INT16_NV",
+        0x8FE4,
+        "GL_INT16_NV",
     },
     {
-        0x8FE5, "GL_INT16_VEC2_NV",
+        0x8FE5,
+        "GL_INT16_VEC2_NV",
     },
     {
-        0x8FE6, "GL_INT16_VEC3_NV",
+        0x8FE6,
+        "GL_INT16_VEC3_NV",
     },
     {
-        0x8FE7, "GL_INT16_VEC4_NV",
+        0x8FE7,
+        "GL_INT16_VEC4_NV",
     },
     {
-        0x8FE9, "GL_INT64_VEC2_NV",
+        0x8FE9,
+        "GL_INT64_VEC2_NV",
     },
     {
-        0x8FEA, "GL_INT64_VEC3_NV",
+        0x8FEA,
+        "GL_INT64_VEC3_NV",
     },
     {
-        0x8FEB, "GL_INT64_VEC4_NV",
+        0x8FEB,
+        "GL_INT64_VEC4_NV",
     },
     {
-        0x8FEC, "GL_UNSIGNED_INT8_NV",
+        0x8FEC,
+        "GL_UNSIGNED_INT8_NV",
     },
     {
-        0x8FED, "GL_UNSIGNED_INT8_VEC2_NV",
+        0x8FED,
+        "GL_UNSIGNED_INT8_VEC2_NV",
     },
     {
-        0x8FEE, "GL_UNSIGNED_INT8_VEC3_NV",
+        0x8FEE,
+        "GL_UNSIGNED_INT8_VEC3_NV",
     },
     {
-        0x8FEF, "GL_UNSIGNED_INT8_VEC4_NV",
+        0x8FEF,
+        "GL_UNSIGNED_INT8_VEC4_NV",
     },
     {
-        0x8FF0, "GL_UNSIGNED_INT16_NV",
+        0x8FF0,
+        "GL_UNSIGNED_INT16_NV",
     },
     {
-        0x8FF1, "GL_UNSIGNED_INT16_VEC2_NV",
+        0x8FF1,
+        "GL_UNSIGNED_INT16_VEC2_NV",
     },
     {
-        0x8FF2, "GL_UNSIGNED_INT16_VEC3_NV",
+        0x8FF2,
+        "GL_UNSIGNED_INT16_VEC3_NV",
     },
     {
-        0x8FF3, "GL_UNSIGNED_INT16_VEC4_NV",
+        0x8FF3,
+        "GL_UNSIGNED_INT16_VEC4_NV",
     },
     {
-        0x8FF5, "GL_UNSIGNED_INT64_VEC2_NV",
+        0x8FF5,
+        "GL_UNSIGNED_INT64_VEC2_NV",
     },
     {
-        0x8FF6, "GL_UNSIGNED_INT64_VEC3_NV",
+        0x8FF6,
+        "GL_UNSIGNED_INT64_VEC3_NV",
     },
     {
-        0x8FF7, "GL_UNSIGNED_INT64_VEC4_NV",
+        0x8FF7,
+        "GL_UNSIGNED_INT64_VEC4_NV",
     },
     {
-        0x8FF8, "GL_FLOAT16_NV",
+        0x8FF8,
+        "GL_FLOAT16_NV",
     },
     {
-        0x8FF9, "GL_FLOAT16_VEC2_NV",
+        0x8FF9,
+        "GL_FLOAT16_VEC2_NV",
     },
     {
-        0x8FFA, "GL_FLOAT16_VEC3_NV",
+        0x8FFA,
+        "GL_FLOAT16_VEC3_NV",
     },
     {
-        0x8FFB, "GL_FLOAT16_VEC4_NV",
+        0x8FFB,
+        "GL_FLOAT16_VEC4_NV",
     },
     {
-        0x9009, "GL_TEXTURE_CUBE_MAP_ARRAY_OES",
+        0x9009,
+        "GL_TEXTURE_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x900A, "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES",
+        0x900A,
+        "GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x900C, "GL_SAMPLER_CUBE_MAP_ARRAY_OES",
+        0x900C,
+        "GL_SAMPLER_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x900D, "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES",
+        0x900D,
+        "GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_OES",
     },
     {
-        0x900E, "GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES",
+        0x900E,
+        "GL_INT_SAMPLER_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x900F, "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES",
+        0x900F,
+        "GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x901C, "GL_FACTOR_MIN_AMD",
+        0x901C,
+        "GL_FACTOR_MIN_AMD",
     },
     {
-        0x901D, "GL_FACTOR_MAX_AMD",
+        0x901D,
+        "GL_FACTOR_MAX_AMD",
     },
     {
-        0x904D, "GL_IMAGE_2D",
+        0x904D,
+        "GL_IMAGE_2D",
     },
     {
-        0x904E, "GL_IMAGE_3D",
+        0x904E,
+        "GL_IMAGE_3D",
     },
     {
-        0x9050, "GL_IMAGE_CUBE",
+        0x9050,
+        "GL_IMAGE_CUBE",
     },
     {
-        0x9051, "GL_IMAGE_BUFFER_OES",
+        0x9051,
+        "GL_IMAGE_BUFFER_OES",
     },
     {
-        0x9053, "GL_IMAGE_2D_ARRAY",
+        0x9053,
+        "GL_IMAGE_2D_ARRAY",
     },
     {
-        0x9054, "GL_IMAGE_CUBE_MAP_ARRAY_OES",
+        0x9054,
+        "GL_IMAGE_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x9058, "GL_INT_IMAGE_2D",
+        0x9058,
+        "GL_INT_IMAGE_2D",
     },
     {
-        0x9059, "GL_INT_IMAGE_3D",
+        0x9059,
+        "GL_INT_IMAGE_3D",
     },
     {
-        0x905B, "GL_INT_IMAGE_CUBE",
+        0x905B,
+        "GL_INT_IMAGE_CUBE",
     },
     {
-        0x905C, "GL_INT_IMAGE_BUFFER_OES",
+        0x905C,
+        "GL_INT_IMAGE_BUFFER_OES",
     },
     {
-        0x905E, "GL_INT_IMAGE_2D_ARRAY",
+        0x905E,
+        "GL_INT_IMAGE_2D_ARRAY",
     },
     {
-        0x905F, "GL_INT_IMAGE_CUBE_MAP_ARRAY_OES",
+        0x905F,
+        "GL_INT_IMAGE_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x9063, "GL_UNSIGNED_INT_IMAGE_2D",
+        0x9063,
+        "GL_UNSIGNED_INT_IMAGE_2D",
     },
     {
-        0x9064, "GL_UNSIGNED_INT_IMAGE_3D",
+        0x9064,
+        "GL_UNSIGNED_INT_IMAGE_3D",
     },
     {
-        0x9066, "GL_UNSIGNED_INT_IMAGE_CUBE",
+        0x9066,
+        "GL_UNSIGNED_INT_IMAGE_CUBE",
     },
     {
-        0x9067, "GL_UNSIGNED_INT_IMAGE_BUFFER_OES",
+        0x9067,
+        "GL_UNSIGNED_INT_IMAGE_BUFFER_OES",
     },
     {
-        0x9069, "GL_UNSIGNED_INT_IMAGE_2D_ARRAY",
+        0x9069,
+        "GL_UNSIGNED_INT_IMAGE_2D_ARRAY",
     },
     {
-        0x906A, "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES",
+        0x906A,
+        "GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_OES",
     },
     {
-        0x906E, "GL_IMAGE_BINDING_FORMAT",
+        0x906E,
+        "GL_IMAGE_BINDING_FORMAT",
     },
     {
-        0x906F, "GL_RGB10_A2UI",
+        0x906F,
+        "GL_RGB10_A2UI",
     },
     {
-        0x9070, "GL_PATH_FORMAT_SVG_NV",
+        0x9070,
+        "GL_PATH_FORMAT_SVG_NV",
     },
     {
-        0x9071, "GL_PATH_FORMAT_PS_NV",
+        0x9071,
+        "GL_PATH_FORMAT_PS_NV",
     },
     {
-        0x9072, "GL_STANDARD_FONT_NAME_NV",
+        0x9072,
+        "GL_STANDARD_FONT_NAME_NV",
     },
     {
-        0x9073, "GL_SYSTEM_FONT_NAME_NV",
+        0x9073,
+        "GL_SYSTEM_FONT_NAME_NV",
     },
     {
-        0x9074, "GL_FILE_NAME_NV",
+        0x9074,
+        "GL_FILE_NAME_NV",
     },
     {
-        0x9075, "GL_PATH_STROKE_WIDTH_NV",
+        0x9075,
+        "GL_PATH_STROKE_WIDTH_NV",
     },
     {
-        0x9076, "GL_PATH_END_CAPS_NV",
+        0x9076,
+        "GL_PATH_END_CAPS_NV",
     },
     {
-        0x9077, "GL_PATH_INITIAL_END_CAP_NV",
+        0x9077,
+        "GL_PATH_INITIAL_END_CAP_NV",
     },
     {
-        0x9078, "GL_PATH_TERMINAL_END_CAP_NV",
+        0x9078,
+        "GL_PATH_TERMINAL_END_CAP_NV",
     },
     {
-        0x9079, "GL_PATH_JOIN_STYLE_NV",
+        0x9079,
+        "GL_PATH_JOIN_STYLE_NV",
     },
     {
-        0x907A, "GL_PATH_MITER_LIMIT_NV",
+        0x907A,
+        "GL_PATH_MITER_LIMIT_NV",
     },
     {
-        0x907B, "GL_PATH_DASH_CAPS_NV",
+        0x907B,
+        "GL_PATH_DASH_CAPS_NV",
     },
     {
-        0x907C, "GL_PATH_INITIAL_DASH_CAP_NV",
+        0x907C,
+        "GL_PATH_INITIAL_DASH_CAP_NV",
     },
     {
-        0x907D, "GL_PATH_TERMINAL_DASH_CAP_NV",
+        0x907D,
+        "GL_PATH_TERMINAL_DASH_CAP_NV",
     },
     {
-        0x907E, "GL_PATH_DASH_OFFSET_NV",
+        0x907E,
+        "GL_PATH_DASH_OFFSET_NV",
     },
     {
-        0x907F, "GL_PATH_CLIENT_LENGTH_NV",
+        0x907F,
+        "GL_PATH_CLIENT_LENGTH_NV",
     },
     {
-        0x907a, "GL_PATH_MITER_LIMIT_CHROMIUM",
+        0x907a,
+        "GL_PATH_MITER_LIMIT_CHROMIUM",
     },
     {
-        0x9080, "GL_PATH_FILL_MODE_NV",
+        0x9080,
+        "GL_PATH_FILL_MODE_NV",
     },
     {
-        0x9081, "GL_PATH_FILL_MASK_NV",
+        0x9081,
+        "GL_PATH_FILL_MASK_NV",
     },
     {
-        0x9082, "GL_PATH_FILL_COVER_MODE_NV",
+        0x9082,
+        "GL_PATH_FILL_COVER_MODE_NV",
     },
     {
-        0x9083, "GL_PATH_STROKE_COVER_MODE_NV",
+        0x9083,
+        "GL_PATH_STROKE_COVER_MODE_NV",
     },
     {
-        0x9084, "GL_PATH_STROKE_MASK_NV",
+        0x9084,
+        "GL_PATH_STROKE_MASK_NV",
     },
     {
-        0x9086, "GL_PATH_STROKE_BOUND_CHROMIUM",
+        0x9086,
+        "GL_PATH_STROKE_BOUND_CHROMIUM",
     },
     {
-        0x9088, "GL_COUNT_UP_NV",
+        0x9088,
+        "GL_COUNT_UP_NV",
     },
     {
-        0x9089, "GL_COUNT_DOWN_NV",
+        0x9089,
+        "GL_COUNT_DOWN_NV",
     },
     {
-        0x908A, "GL_PATH_OBJECT_BOUNDING_BOX_NV",
+        0x908A,
+        "GL_PATH_OBJECT_BOUNDING_BOX_NV",
     },
     {
-        0x908B, "GL_CONVEX_HULL_NV",
+        0x908B,
+        "GL_CONVEX_HULL_NV",
     },
     {
-        0x908D, "GL_BOUNDING_BOX_NV",
+        0x908D,
+        "GL_BOUNDING_BOX_NV",
     },
     {
-        0x908E, "GL_TRANSLATE_X_NV",
+        0x908E,
+        "GL_TRANSLATE_X_NV",
     },
     {
-        0x908F, "GL_TRANSLATE_Y_NV",
+        0x908F,
+        "GL_TRANSLATE_Y_NV",
     },
     {
-        0x9090, "GL_TRANSLATE_2D_NV",
+        0x9090,
+        "GL_TRANSLATE_2D_NV",
     },
     {
-        0x9091, "GL_TRANSLATE_3D_NV",
+        0x9091,
+        "GL_TRANSLATE_3D_NV",
     },
     {
-        0x9092, "GL_AFFINE_2D_NV",
+        0x9092,
+        "GL_AFFINE_2D_NV",
     },
     {
-        0x9094, "GL_AFFINE_3D_NV",
+        0x9094,
+        "GL_AFFINE_3D_NV",
     },
     {
-        0x9096, "GL_TRANSPOSE_AFFINE_2D_NV",
+        0x9096,
+        "GL_TRANSPOSE_AFFINE_2D_NV",
     },
     {
-        0x9098, "GL_TRANSPOSE_AFFINE_3D_NV",
+        0x9098,
+        "GL_TRANSPOSE_AFFINE_3D_NV",
     },
     {
-        0x909A, "GL_UTF8_NV",
+        0x909A,
+        "GL_UTF8_NV",
     },
     {
-        0x909B, "GL_UTF16_NV",
+        0x909B,
+        "GL_UTF16_NV",
     },
     {
-        0x909C, "GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV",
+        0x909C,
+        "GL_BOUNDING_BOX_OF_BOUNDING_BOXES_NV",
     },
     {
-        0x909D, "GL_PATH_COMMAND_COUNT_NV",
+        0x909D,
+        "GL_PATH_COMMAND_COUNT_NV",
     },
     {
-        0x909E, "GL_PATH_COORD_COUNT_NV",
+        0x909E,
+        "GL_PATH_COORD_COUNT_NV",
     },
     {
-        0x909F, "GL_PATH_DASH_ARRAY_COUNT_NV",
+        0x909F,
+        "GL_PATH_DASH_ARRAY_COUNT_NV",
     },
     {
-        0x90A0, "GL_PATH_COMPUTED_LENGTH_NV",
+        0x90A0,
+        "GL_PATH_COMPUTED_LENGTH_NV",
     },
     {
-        0x90A1, "GL_PATH_FILL_BOUNDING_BOX_NV",
+        0x90A1,
+        "GL_PATH_FILL_BOUNDING_BOX_NV",
     },
     {
-        0x90A2, "GL_PATH_STROKE_BOUNDING_BOX_NV",
+        0x90A2,
+        "GL_PATH_STROKE_BOUNDING_BOX_NV",
     },
     {
-        0x90A3, "GL_SQUARE_NV",
+        0x90A3,
+        "GL_SQUARE_NV",
     },
     {
-        0x90A4, "GL_ROUND_NV",
+        0x90A4,
+        "GL_ROUND_NV",
     },
     {
-        0x90A5, "GL_TRIANGULAR_NV",
+        0x90A5,
+        "GL_TRIANGULAR_NV",
     },
     {
-        0x90A6, "GL_BEVEL_NV",
+        0x90A6,
+        "GL_BEVEL_NV",
     },
     {
-        0x90A7, "GL_MITER_REVERT_NV",
+        0x90A7,
+        "GL_MITER_REVERT_NV",
     },
     {
-        0x90A8, "GL_MITER_TRUNCATE_NV",
+        0x90A8,
+        "GL_MITER_TRUNCATE_NV",
     },
     {
-        0x90A9, "GL_SKIP_MISSING_GLYPH_NV",
+        0x90A9,
+        "GL_SKIP_MISSING_GLYPH_NV",
     },
     {
-        0x90AA, "GL_USE_MISSING_GLYPH_NV",
+        0x90AA,
+        "GL_USE_MISSING_GLYPH_NV",
     },
     {
-        0x90AB, "GL_PATH_ERROR_POSITION_NV",
+        0x90AB,
+        "GL_PATH_ERROR_POSITION_NV",
     },
     {
-        0x90AD, "GL_ACCUM_ADJACENT_PAIRS_NV",
+        0x90AD,
+        "GL_ACCUM_ADJACENT_PAIRS_NV",
     },
     {
-        0x90AE, "GL_ADJACENT_PAIRS_NV",
+        0x90AE,
+        "GL_ADJACENT_PAIRS_NV",
     },
     {
-        0x90AF, "GL_FIRST_TO_REST_NV",
+        0x90AF,
+        "GL_FIRST_TO_REST_NV",
     },
     {
-        0x90B0, "GL_PATH_GEN_MODE_NV",
+        0x90B0,
+        "GL_PATH_GEN_MODE_NV",
     },
     {
-        0x90B1, "GL_PATH_GEN_COEFF_NV",
+        0x90B1,
+        "GL_PATH_GEN_COEFF_NV",
     },
     {
-        0x90B3, "GL_PATH_GEN_COMPONENTS_NV",
+        0x90B3,
+        "GL_PATH_GEN_COMPONENTS_NV",
     },
     {
-        0x90B4, "GL_PATH_DASH_OFFSET_RESET_NV",
+        0x90B4,
+        "GL_PATH_DASH_OFFSET_RESET_NV",
     },
     {
-        0x90B5, "GL_MOVE_TO_RESETS_NV",
+        0x90B5,
+        "GL_MOVE_TO_RESETS_NV",
     },
     {
-        0x90B6, "GL_MOVE_TO_CONTINUES_NV",
+        0x90B6,
+        "GL_MOVE_TO_CONTINUES_NV",
     },
     {
-        0x90B7, "GL_PATH_STENCIL_FUNC_NV",
+        0x90B7,
+        "GL_PATH_STENCIL_FUNC_NV",
     },
     {
-        0x90B8, "GL_PATH_STENCIL_REF_NV",
+        0x90B8,
+        "GL_PATH_STENCIL_REF_NV",
     },
     {
-        0x90B9, "GL_PATH_STENCIL_VALUE_MASK_NV",
+        0x90B9,
+        "GL_PATH_STENCIL_VALUE_MASK_NV",
     },
     {
-        0x90BD, "GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV",
+        0x90BD,
+        "GL_PATH_STENCIL_DEPTH_OFFSET_FACTOR_NV",
     },
     {
-        0x90BE, "GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV",
+        0x90BE,
+        "GL_PATH_STENCIL_DEPTH_OFFSET_UNITS_NV",
     },
     {
-        0x90BF, "GL_PATH_COVER_DEPTH_FUNC_NV",
+        0x90BF,
+        "GL_PATH_COVER_DEPTH_FUNC_NV",
     },
     {
-        0x90C7, "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE",
+        0x90C7,
+        "GL_IMAGE_FORMAT_COMPATIBILITY_TYPE",
     },
     {
-        0x90C8, "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE",
+        0x90C8,
+        "GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE",
     },
     {
-        0x90C9, "GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS",
+        0x90C9,
+        "GL_IMAGE_FORMAT_COMPATIBILITY_BY_CLASS",
     },
     {
-        0x90CA, "GL_MAX_VERTEX_IMAGE_UNIFORMS",
+        0x90CA,
+        "GL_MAX_VERTEX_IMAGE_UNIFORMS",
     },
     {
-        0x90CB, "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES",
+        0x90CB,
+        "GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_OES",
     },
     {
-        0x90CC, "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES",
+        0x90CC,
+        "GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_OES",
     },
     {
-        0x90CD, "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES",
+        0x90CD,
+        "GL_MAX_GEOMETRY_IMAGE_UNIFORMS_OES",
     },
     {
-        0x90CE, "GL_MAX_FRAGMENT_IMAGE_UNIFORMS",
+        0x90CE,
+        "GL_MAX_FRAGMENT_IMAGE_UNIFORMS",
     },
     {
-        0x90CF, "GL_MAX_COMBINED_IMAGE_UNIFORMS",
+        0x90CF,
+        "GL_MAX_COMBINED_IMAGE_UNIFORMS",
     },
     {
-        0x90D2, "GL_SHADER_STORAGE_BUFFER",
+        0x90D2,
+        "GL_SHADER_STORAGE_BUFFER",
     },
     {
-        0x90D3, "GL_SHADER_STORAGE_BUFFER_BINDING",
+        0x90D3,
+        "GL_SHADER_STORAGE_BUFFER_BINDING",
     },
     {
-        0x90D4, "GL_SHADER_STORAGE_BUFFER_START",
+        0x90D4,
+        "GL_SHADER_STORAGE_BUFFER_START",
     },
     {
-        0x90D5, "GL_SHADER_STORAGE_BUFFER_SIZE",
+        0x90D5,
+        "GL_SHADER_STORAGE_BUFFER_SIZE",
     },
     {
-        0x90D6, "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS",
+        0x90D6,
+        "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS",
     },
     {
-        0x90D7, "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES",
+        0x90D7,
+        "GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_OES",
     },
     {
-        0x90D8, "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES",
+        0x90D8,
+        "GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_OES",
     },
     {
-        0x90D9, "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES",
+        0x90D9,
+        "GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_OES",
     },
     {
-        0x90DA, "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS",
+        0x90DA,
+        "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS",
     },
     {
-        0x90DB, "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS",
+        0x90DB,
+        "GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS",
     },
     {
-        0x90DC, "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS",
+        0x90DC,
+        "GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS",
     },
     {
-        0x90DD, "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS",
+        0x90DD,
+        "GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS",
     },
     {
-        0x90DE, "GL_MAX_SHADER_STORAGE_BLOCK_SIZE",
+        0x90DE,
+        "GL_MAX_SHADER_STORAGE_BLOCK_SIZE",
     },
     {
-        0x90DF, "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT",
+        0x90DF,
+        "GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT",
     },
     {
-        0x90EA, "GL_DEPTH_STENCIL_TEXTURE_MODE",
+        0x90EA,
+        "GL_DEPTH_STENCIL_TEXTURE_MODE",
     },
     {
-        0x90EB, "GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS",
+        0x90EB,
+        "GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS",
     },
     {
-        0x90EE, "GL_DISPATCH_INDIRECT_BUFFER",
+        0x90EE,
+        "GL_DISPATCH_INDIRECT_BUFFER",
     },
     {
-        0x90EF, "GL_DISPATCH_INDIRECT_BUFFER_BINDING",
+        0x90EF,
+        "GL_DISPATCH_INDIRECT_BUFFER_BINDING",
     },
     {
-        0x90F0, "GL_COLOR_ATTACHMENT_EXT",
+        0x90F0,
+        "GL_COLOR_ATTACHMENT_EXT",
     },
     {
-        0x90F1, "GL_MULTIVIEW_EXT",
+        0x90F1,
+        "GL_MULTIVIEW_EXT",
     },
     {
-        0x90F2, "GL_MAX_MULTIVIEW_BUFFERS_EXT",
+        0x90F2,
+        "GL_MAX_MULTIVIEW_BUFFERS_EXT",
     },
     {
-        0x90F3, "GL_CONTEXT_ROBUST_ACCESS_KHR",
+        0x90F3,
+        "GL_CONTEXT_ROBUST_ACCESS_KHR",
     },
     {
-        0x90a3, "GL_SQUARE_CHROMIUM",
+        0x90a3,
+        "GL_SQUARE_CHROMIUM",
     },
     {
-        0x90a4, "GL_ROUND_CHROMIUM",
+        0x90a4,
+        "GL_ROUND_CHROMIUM",
     },
     {
-        0x9100, "GL_TEXTURE_2D_MULTISAMPLE",
+        0x9100,
+        "GL_TEXTURE_2D_MULTISAMPLE",
     },
     {
-        0x9102, "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES",
+        0x9102,
+        "GL_TEXTURE_2D_MULTISAMPLE_ARRAY_OES",
     },
     {
-        0x9104, "GL_TEXTURE_BINDING_2D_MULTISAMPLE",
+        0x9104,
+        "GL_TEXTURE_BINDING_2D_MULTISAMPLE",
     },
     {
-        0x9105, "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES",
+        0x9105,
+        "GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY_OES",
     },
     {
-        0x9106, "GL_TEXTURE_SAMPLES",
+        0x9106,
+        "GL_TEXTURE_SAMPLES",
     },
     {
-        0x9107, "GL_TEXTURE_FIXED_SAMPLE_LOCATIONS",
+        0x9107,
+        "GL_TEXTURE_FIXED_SAMPLE_LOCATIONS",
     },
     {
-        0x9108, "GL_SAMPLER_2D_MULTISAMPLE",
+        0x9108,
+        "GL_SAMPLER_2D_MULTISAMPLE",
     },
     {
-        0x9109, "GL_INT_SAMPLER_2D_MULTISAMPLE",
+        0x9109,
+        "GL_INT_SAMPLER_2D_MULTISAMPLE",
     },
     {
-        0x910A, "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE",
+        0x910A,
+        "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE",
     },
     {
-        0x910B, "GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
+        0x910B,
+        "GL_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
     },
     {
-        0x910C, "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
+        0x910C,
+        "GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
     },
     {
-        0x910D, "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
+        0x910D,
+        "GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY_OES",
     },
     {
-        0x910E, "GL_MAX_COLOR_TEXTURE_SAMPLES",
+        0x910E,
+        "GL_MAX_COLOR_TEXTURE_SAMPLES",
     },
     {
-        0x910F, "GL_MAX_DEPTH_TEXTURE_SAMPLES",
+        0x910F,
+        "GL_MAX_DEPTH_TEXTURE_SAMPLES",
     },
     {
-        0x9110, "GL_MAX_INTEGER_SAMPLES",
+        0x9110,
+        "GL_MAX_INTEGER_SAMPLES",
     },
     {
-        0x9111, "GL_MAX_SERVER_WAIT_TIMEOUT_APPLE",
+        0x9111,
+        "GL_MAX_SERVER_WAIT_TIMEOUT_APPLE",
     },
     {
-        0x9112, "GL_OBJECT_TYPE_APPLE",
+        0x9112,
+        "GL_OBJECT_TYPE_APPLE",
     },
     {
-        0x9113, "GL_SYNC_CONDITION_APPLE",
+        0x9113,
+        "GL_SYNC_CONDITION_APPLE",
     },
     {
-        0x9114, "GL_SYNC_STATUS_APPLE",
+        0x9114,
+        "GL_SYNC_STATUS_APPLE",
     },
     {
-        0x9115, "GL_SYNC_FLAGS_APPLE",
+        0x9115,
+        "GL_SYNC_FLAGS_APPLE",
     },
     {
-        0x9116, "GL_SYNC_FENCE_APPLE",
+        0x9116,
+        "GL_SYNC_FENCE_APPLE",
     },
     {
-        0x9117, "GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE",
+        0x9117,
+        "GL_SYNC_GPU_COMMANDS_COMPLETE_APPLE",
     },
     {
-        0x9118, "GL_UNSIGNALED_APPLE",
+        0x9118,
+        "GL_UNSIGNALED_APPLE",
     },
     {
-        0x9119, "GL_SIGNALED_APPLE",
+        0x9119,
+        "GL_SIGNALED_APPLE",
     },
     {
-        0x911A, "GL_ALREADY_SIGNALED_APPLE",
+        0x911A,
+        "GL_ALREADY_SIGNALED_APPLE",
     },
     {
-        0x911B, "GL_TIMEOUT_EXPIRED_APPLE",
+        0x911B,
+        "GL_TIMEOUT_EXPIRED_APPLE",
     },
     {
-        0x911C, "GL_CONDITION_SATISFIED_APPLE",
+        0x911C,
+        "GL_CONDITION_SATISFIED_APPLE",
     },
     {
-        0x911D, "GL_WAIT_FAILED_APPLE",
+        0x911D,
+        "GL_WAIT_FAILED_APPLE",
     },
     {
-        0x911F, "GL_BUFFER_ACCESS_FLAGS",
+        0x911F,
+        "GL_BUFFER_ACCESS_FLAGS",
     },
     {
-        0x9120, "GL_BUFFER_MAP_LENGTH",
+        0x9120,
+        "GL_BUFFER_MAP_LENGTH",
     },
     {
-        0x9121, "GL_BUFFER_MAP_OFFSET",
+        0x9121,
+        "GL_BUFFER_MAP_OFFSET",
     },
     {
-        0x9122, "GL_MAX_VERTEX_OUTPUT_COMPONENTS",
+        0x9122,
+        "GL_MAX_VERTEX_OUTPUT_COMPONENTS",
     },
     {
-        0x9123, "GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES",
+        0x9123,
+        "GL_MAX_GEOMETRY_INPUT_COMPONENTS_OES",
     },
     {
-        0x9124, "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES",
+        0x9124,
+        "GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_OES",
     },
     {
-        0x9125, "GL_MAX_FRAGMENT_INPUT_COMPONENTS",
+        0x9125,
+        "GL_MAX_FRAGMENT_INPUT_COMPONENTS",
     },
     {
-        0x912F, "GL_TEXTURE_IMMUTABLE_FORMAT_EXT",
+        0x912F,
+        "GL_TEXTURE_IMMUTABLE_FORMAT_EXT",
     },
     {
-        0x9130, "GL_SGX_PROGRAM_BINARY_IMG",
+        0x9130,
+        "GL_SGX_PROGRAM_BINARY_IMG",
     },
     {
-        0x9133, "GL_RENDERBUFFER_SAMPLES_IMG",
+        0x9133,
+        "GL_RENDERBUFFER_SAMPLES_IMG",
     },
     {
-        0x9134, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG",
+        0x9134,
+        "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG",
     },
     {
-        0x9135, "GL_MAX_SAMPLES_IMG",
+        0x9135,
+        "GL_MAX_SAMPLES_IMG",
     },
     {
-        0x9136, "GL_TEXTURE_SAMPLES_IMG",
+        0x9136,
+        "GL_TEXTURE_SAMPLES_IMG",
     },
     {
-        0x9137, "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG",
+        0x9137,
+        "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG",
     },
     {
-        0x9138, "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG",
+        0x9138,
+        "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG",
     },
     {
-        0x9139, "GL_CUBIC_IMG",
+        0x9139,
+        "GL_CUBIC_IMG",
     },
     {
-        0x913A, "GL_CUBIC_MIPMAP_NEAREST_IMG",
+        0x913A,
+        "GL_CUBIC_MIPMAP_NEAREST_IMG",
     },
     {
-        0x913B, "GL_CUBIC_MIPMAP_LINEAR_IMG",
+        0x913B,
+        "GL_CUBIC_MIPMAP_LINEAR_IMG",
     },
     {
-        0x913C, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG",
+        0x913C,
+        "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_AND_DOWNSAMPLE_IMG",
     },
     {
-        0x913D, "GL_NUM_DOWNSAMPLE_SCALES_IMG",
+        0x913D,
+        "GL_NUM_DOWNSAMPLE_SCALES_IMG",
     },
     {
-        0x913E, "GL_DOWNSAMPLE_SCALES_IMG",
+        0x913E,
+        "GL_DOWNSAMPLE_SCALES_IMG",
     },
     {
-        0x913F, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG",
+        0x913F,
+        "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SCALE_IMG",
     },
     {
-        0x9143, "GL_MAX_DEBUG_MESSAGE_LENGTH_KHR",
+        0x9143,
+        "GL_MAX_DEBUG_MESSAGE_LENGTH_KHR",
     },
     {
-        0x9144, "GL_MAX_DEBUG_LOGGED_MESSAGES_KHR",
+        0x9144,
+        "GL_MAX_DEBUG_LOGGED_MESSAGES_KHR",
     },
     {
-        0x9145, "GL_DEBUG_LOGGED_MESSAGES_KHR",
+        0x9145,
+        "GL_DEBUG_LOGGED_MESSAGES_KHR",
     },
     {
-        0x9146, "GL_DEBUG_SEVERITY_HIGH_KHR",
+        0x9146,
+        "GL_DEBUG_SEVERITY_HIGH_KHR",
     },
     {
-        0x9147, "GL_DEBUG_SEVERITY_MEDIUM_KHR",
+        0x9147,
+        "GL_DEBUG_SEVERITY_MEDIUM_KHR",
     },
     {
-        0x9148, "GL_DEBUG_SEVERITY_LOW_KHR",
+        0x9148,
+        "GL_DEBUG_SEVERITY_LOW_KHR",
     },
     {
-        0x9151, "GL_BUFFER_OBJECT_EXT",
+        0x9151,
+        "GL_BUFFER_OBJECT_EXT",
     },
     {
-        0x9153, "GL_QUERY_OBJECT_EXT",
+        0x9153,
+        "GL_QUERY_OBJECT_EXT",
     },
     {
-        0x9154, "GL_VERTEX_ARRAY_OBJECT_EXT",
+        0x9154,
+        "GL_VERTEX_ARRAY_OBJECT_EXT",
     },
     {
-        0x9195, "GL_VIRTUAL_PAGE_SIZE_X_EXT",
+        0x9195,
+        "GL_VIRTUAL_PAGE_SIZE_X_EXT",
     },
     {
-        0x9196, "GL_VIRTUAL_PAGE_SIZE_Y_EXT",
+        0x9196,
+        "GL_VIRTUAL_PAGE_SIZE_Y_EXT",
     },
     {
-        0x9197, "GL_VIRTUAL_PAGE_SIZE_Z_EXT",
+        0x9197,
+        "GL_VIRTUAL_PAGE_SIZE_Z_EXT",
     },
     {
-        0x9198, "GL_MAX_SPARSE_TEXTURE_SIZE_EXT",
+        0x9198,
+        "GL_MAX_SPARSE_TEXTURE_SIZE_EXT",
     },
     {
-        0x9199, "GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT",
+        0x9199,
+        "GL_MAX_SPARSE_3D_TEXTURE_SIZE_EXT",
     },
     {
-        0x919A, "GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT",
+        0x919A,
+        "GL_MAX_SPARSE_ARRAY_TEXTURE_LAYERS_EXT",
     },
     {
-        0x919D, "GL_TEXTURE_BUFFER_OFFSET_OES",
+        0x919D,
+        "GL_TEXTURE_BUFFER_OFFSET_OES",
     },
     {
-        0x919E, "GL_TEXTURE_BUFFER_SIZE_OES",
+        0x919E,
+        "GL_TEXTURE_BUFFER_SIZE_OES",
     },
     {
-        0x919F, "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES",
+        0x919F,
+        "GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT_OES",
     },
     {
-        0x91A6, "GL_TEXTURE_SPARSE_EXT",
+        0x91A6,
+        "GL_TEXTURE_SPARSE_EXT",
     },
     {
-        0x91A7, "GL_VIRTUAL_PAGE_SIZE_INDEX_EXT",
+        0x91A7,
+        "GL_VIRTUAL_PAGE_SIZE_INDEX_EXT",
     },
     {
-        0x91A8, "GL_NUM_VIRTUAL_PAGE_SIZES_EXT",
+        0x91A8,
+        "GL_NUM_VIRTUAL_PAGE_SIZES_EXT",
     },
     {
-        0x91A9, "GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT",
+        0x91A9,
+        "GL_SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_EXT",
     },
     {
-        0x91AA, "GL_NUM_SPARSE_LEVELS_EXT",
+        0x91AA,
+        "GL_NUM_SPARSE_LEVELS_EXT",
     },
     {
-        0x91B0, "GL_MAX_SHADER_COMPILER_THREADS_KHR",
+        0x91B0,
+        "GL_MAX_SHADER_COMPILER_THREADS_KHR",
     },
     {
-        0x91B1, "GL_COMPLETION_STATUS_KHR",
+        0x91B1,
+        "GL_COMPLETION_STATUS_KHR",
     },
     {
-        0x91B2, "GL_RENDERBUFFER_STORAGE_SAMPLES_AMD",
+        0x91B2,
+        "GL_RENDERBUFFER_STORAGE_SAMPLES_AMD",
     },
     {
-        0x91B3, "GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD",
+        0x91B3,
+        "GL_MAX_COLOR_FRAMEBUFFER_SAMPLES_AMD",
     },
     {
-        0x91B4, "GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD",
+        0x91B4,
+        "GL_MAX_COLOR_FRAMEBUFFER_STORAGE_SAMPLES_AMD",
     },
     {
-        0x91B5, "GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD",
+        0x91B5,
+        "GL_MAX_DEPTH_STENCIL_FRAMEBUFFER_SAMPLES_AMD",
     },
     {
-        0x91B6, "GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD",
+        0x91B6,
+        "GL_NUM_SUPPORTED_MULTISAMPLE_MODES_AMD",
     },
     {
-        0x91B7, "GL_SUPPORTED_MULTISAMPLE_MODES_AMD",
+        0x91B7,
+        "GL_SUPPORTED_MULTISAMPLE_MODES_AMD",
     },
     {
-        0x91B9, "GL_COMPUTE_SHADER",
+        0x91B9,
+        "GL_COMPUTE_SHADER",
     },
     {
-        0x91BB, "GL_MAX_COMPUTE_UNIFORM_BLOCKS",
+        0x91BB,
+        "GL_MAX_COMPUTE_UNIFORM_BLOCKS",
     },
     {
-        0x91BC, "GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS",
+        0x91BC,
+        "GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS",
     },
     {
-        0x91BD, "GL_MAX_COMPUTE_IMAGE_UNIFORMS",
+        0x91BD,
+        "GL_MAX_COMPUTE_IMAGE_UNIFORMS",
     },
     {
-        0x91BE, "GL_MAX_COMPUTE_WORK_GROUP_COUNT",
+        0x91BE,
+        "GL_MAX_COMPUTE_WORK_GROUP_COUNT",
     },
     {
-        0x91BF, "GL_MAX_COMPUTE_WORK_GROUP_SIZE",
+        0x91BF,
+        "GL_MAX_COMPUTE_WORK_GROUP_SIZE",
     },
     {
-        0x9243, "GL_UNPACK_COLORSPACE_CONVERSION_CHROMIUM",
+        0x9243,
+        "GL_UNPACK_COLORSPACE_CONVERSION_CHROMIUM",
     },
     {
-        0x9244, "GL_BIND_GENERATES_RESOURCE_CHROMIUM",
+        0x9244,
+        "GL_BIND_GENERATES_RESOURCE_CHROMIUM",
     },
     {
-        0x9245, "GL_OVERLAY_TRANSFORM_NONE_CHROMIUM",
+        0x9245,
+        "GL_OVERLAY_TRANSFORM_NONE_CHROMIUM",
     },
     {
-        0x9246, "GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM",
+        0x9246,
+        "GL_OVERLAY_TRANSFORM_FLIP_HORIZONTAL_CHROMIUM",
     },
     {
-        0x9247, "GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM",
+        0x9247,
+        "GL_OVERLAY_TRANSFORM_FLIP_VERTICAL_CHROMIUM",
     },
     {
-        0x9248, "GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM",
+        0x9248,
+        "GL_OVERLAY_TRANSFORM_ROTATE_90_CHROMIUM",
     },
     {
-        0x9249, "GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM",
+        0x9249,
+        "GL_OVERLAY_TRANSFORM_ROTATE_180_CHROMIUM",
     },
     {
-        0x924A, "GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM",
+        0x924A,
+        "GL_OVERLAY_TRANSFORM_ROTATE_270_CHROMIUM",
     },
     {
-        0x9250, "GL_SHADER_BINARY_DMP",
+        0x9250,
+        "GL_SHADER_BINARY_DMP",
     },
     {
-        0x9251, "GL_SMAPHS30_PROGRAM_BINARY_DMP",
+        0x9251,
+        "GL_SMAPHS30_PROGRAM_BINARY_DMP",
     },
     {
-        0x9252, "GL_SMAPHS_PROGRAM_BINARY_DMP",
+        0x9252,
+        "GL_SMAPHS_PROGRAM_BINARY_DMP",
     },
     {
-        0x9253, "GL_DMP_PROGRAM_BINARY_DMP",
+        0x9253,
+        "GL_DMP_PROGRAM_BINARY_DMP",
     },
     {
-        0x9260, "GL_GCCSO_SHADER_BINARY_FJ",
+        0x9260,
+        "GL_GCCSO_SHADER_BINARY_FJ",
     },
     {
-        0x9270, "GL_COMPRESSED_R11_EAC",
+        0x9270,
+        "GL_COMPRESSED_R11_EAC",
     },
     {
-        0x9271, "GL_COMPRESSED_SIGNED_R11_EAC",
+        0x9271,
+        "GL_COMPRESSED_SIGNED_R11_EAC",
     },
     {
-        0x9272, "GL_COMPRESSED_RG11_EAC",
+        0x9272,
+        "GL_COMPRESSED_RG11_EAC",
     },
     {
-        0x9273, "GL_COMPRESSED_SIGNED_RG11_EAC",
+        0x9273,
+        "GL_COMPRESSED_SIGNED_RG11_EAC",
     },
     {
-        0x9274, "GL_COMPRESSED_RGB8_ETC2",
+        0x9274,
+        "GL_COMPRESSED_RGB8_ETC2",
     },
     {
-        0x9275, "GL_COMPRESSED_SRGB8_ETC2",
+        0x9275,
+        "GL_COMPRESSED_SRGB8_ETC2",
     },
     {
-        0x9276, "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",
+        0x9276,
+        "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2",
     },
     {
-        0x9277, "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",
+        0x9277,
+        "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2",
     },
     {
-        0x9278, "GL_COMPRESSED_RGBA8_ETC2_EAC",
+        0x9278,
+        "GL_COMPRESSED_RGBA8_ETC2_EAC",
     },
     {
-        0x9279, "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",
+        0x9279,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC",
     },
     {
-        0x9280, "GL_BLEND_PREMULTIPLIED_SRC_NV",
+        0x9280,
+        "GL_BLEND_PREMULTIPLIED_SRC_NV",
     },
     {
-        0x9281, "GL_BLEND_OVERLAP_NV",
+        0x9281,
+        "GL_BLEND_OVERLAP_NV",
     },
     {
-        0x9282, "GL_UNCORRELATED_NV",
+        0x9282,
+        "GL_UNCORRELATED_NV",
     },
     {
-        0x9283, "GL_DISJOINT_NV",
+        0x9283,
+        "GL_DISJOINT_NV",
     },
     {
-        0x9284, "GL_CONJOINT_NV",
+        0x9284,
+        "GL_CONJOINT_NV",
     },
     {
-        0x9285, "GL_BLEND_ADVANCED_COHERENT_KHR",
+        0x9285,
+        "GL_BLEND_ADVANCED_COHERENT_KHR",
     },
     {
-        0x9286, "GL_SRC_NV",
+        0x9286,
+        "GL_SRC_NV",
     },
     {
-        0x9287, "GL_DST_NV",
+        0x9287,
+        "GL_DST_NV",
     },
     {
-        0x9288, "GL_SRC_OVER_NV",
+        0x9288,
+        "GL_SRC_OVER_NV",
     },
     {
-        0x9289, "GL_DST_OVER_NV",
+        0x9289,
+        "GL_DST_OVER_NV",
     },
     {
-        0x928A, "GL_SRC_IN_NV",
+        0x928A,
+        "GL_SRC_IN_NV",
     },
     {
-        0x928B, "GL_DST_IN_NV",
+        0x928B,
+        "GL_DST_IN_NV",
     },
     {
-        0x928C, "GL_SRC_OUT_NV",
+        0x928C,
+        "GL_SRC_OUT_NV",
     },
     {
-        0x928D, "GL_DST_OUT_NV",
+        0x928D,
+        "GL_DST_OUT_NV",
     },
     {
-        0x928E, "GL_SRC_ATOP_NV",
+        0x928E,
+        "GL_SRC_ATOP_NV",
     },
     {
-        0x928F, "GL_DST_ATOP_NV",
+        0x928F,
+        "GL_DST_ATOP_NV",
     },
     {
-        0x9291, "GL_PLUS_NV",
+        0x9291,
+        "GL_PLUS_NV",
     },
     {
-        0x9292, "GL_PLUS_DARKER_NV",
+        0x9292,
+        "GL_PLUS_DARKER_NV",
     },
     {
-        0x9294, "GL_MULTIPLY_KHR",
+        0x9294,
+        "GL_MULTIPLY_KHR",
     },
     {
-        0x9295, "GL_SCREEN_KHR",
+        0x9295,
+        "GL_SCREEN_KHR",
     },
     {
-        0x9296, "GL_OVERLAY_KHR",
+        0x9296,
+        "GL_OVERLAY_KHR",
     },
     {
-        0x9297, "GL_DARKEN_KHR",
+        0x9297,
+        "GL_DARKEN_KHR",
     },
     {
-        0x9298, "GL_LIGHTEN_KHR",
+        0x9298,
+        "GL_LIGHTEN_KHR",
     },
     {
-        0x9299, "GL_COLORDODGE_KHR",
+        0x9299,
+        "GL_COLORDODGE_KHR",
     },
     {
-        0x929A, "GL_COLORBURN_KHR",
+        0x929A,
+        "GL_COLORBURN_KHR",
     },
     {
-        0x929B, "GL_HARDLIGHT_KHR",
+        0x929B,
+        "GL_HARDLIGHT_KHR",
     },
     {
-        0x929C, "GL_SOFTLIGHT_KHR",
+        0x929C,
+        "GL_SOFTLIGHT_KHR",
     },
     {
-        0x929E, "GL_DIFFERENCE_KHR",
+        0x929E,
+        "GL_DIFFERENCE_KHR",
     },
     {
-        0x929F, "GL_MINUS_NV",
+        0x929F,
+        "GL_MINUS_NV",
     },
     {
-        0x92A0, "GL_EXCLUSION_KHR",
+        0x92A0,
+        "GL_EXCLUSION_KHR",
     },
     {
-        0x92A1, "GL_CONTRAST_NV",
+        0x92A1,
+        "GL_CONTRAST_NV",
     },
     {
-        0x92A3, "GL_INVERT_RGB_NV",
+        0x92A3,
+        "GL_INVERT_RGB_NV",
     },
     {
-        0x92A4, "GL_LINEARDODGE_NV",
+        0x92A4,
+        "GL_LINEARDODGE_NV",
     },
     {
-        0x92A5, "GL_LINEARBURN_NV",
+        0x92A5,
+        "GL_LINEARBURN_NV",
     },
     {
-        0x92A6, "GL_VIVIDLIGHT_NV",
+        0x92A6,
+        "GL_VIVIDLIGHT_NV",
     },
     {
-        0x92A7, "GL_LINEARLIGHT_NV",
+        0x92A7,
+        "GL_LINEARLIGHT_NV",
     },
     {
-        0x92A8, "GL_PINLIGHT_NV",
+        0x92A8,
+        "GL_PINLIGHT_NV",
     },
     {
-        0x92A9, "GL_HARDMIX_NV",
+        0x92A9,
+        "GL_HARDMIX_NV",
     },
     {
-        0x92AD, "GL_HSL_HUE_KHR",
+        0x92AD,
+        "GL_HSL_HUE_KHR",
     },
     {
-        0x92AE, "GL_HSL_SATURATION_KHR",
+        0x92AE,
+        "GL_HSL_SATURATION_KHR",
     },
     {
-        0x92AF, "GL_HSL_COLOR_KHR",
+        0x92AF,
+        "GL_HSL_COLOR_KHR",
     },
     {
-        0x92B0, "GL_HSL_LUMINOSITY_KHR",
+        0x92B0,
+        "GL_HSL_LUMINOSITY_KHR",
     },
     {
-        0x92B1, "GL_PLUS_CLAMPED_NV",
+        0x92B1,
+        "GL_PLUS_CLAMPED_NV",
     },
     {
-        0x92B2, "GL_PLUS_CLAMPED_ALPHA_NV",
+        0x92B2,
+        "GL_PLUS_CLAMPED_ALPHA_NV",
     },
     {
-        0x92B3, "GL_MINUS_CLAMPED_NV",
+        0x92B3,
+        "GL_MINUS_CLAMPED_NV",
     },
     {
-        0x92B4, "GL_INVERT_OVG_NV",
+        0x92B4,
+        "GL_INVERT_OVG_NV",
     },
     {
-        0x92BE, "GL_PRIMITIVE_BOUNDING_BOX_OES",
+        0x92BE,
+        "GL_PRIMITIVE_BOUNDING_BOX_OES",
     },
     {
-        0x92C0, "GL_ATOMIC_COUNTER_BUFFER",
+        0x92C0,
+        "GL_ATOMIC_COUNTER_BUFFER",
     },
     {
-        0x92C1, "GL_ATOMIC_COUNTER_BUFFER_BINDING",
+        0x92C1,
+        "GL_ATOMIC_COUNTER_BUFFER_BINDING",
     },
     {
-        0x92C2, "GL_ATOMIC_COUNTER_BUFFER_START",
+        0x92C2,
+        "GL_ATOMIC_COUNTER_BUFFER_START",
     },
     {
-        0x92C3, "GL_ATOMIC_COUNTER_BUFFER_SIZE",
+        0x92C3,
+        "GL_ATOMIC_COUNTER_BUFFER_SIZE",
     },
     {
-        0x92CC, "GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS",
+        0x92CC,
+        "GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS",
     },
     {
-        0x92CD, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES",
+        0x92CD,
+        "GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_OES",
     },
     {
-        0x92CE, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES",
+        0x92CE,
+        "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_OES",
     },
     {
-        0x92CF, "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES",
+        0x92CF,
+        "GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_OES",
     },
     {
-        0x92D0, "GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS",
+        0x92D0,
+        "GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS",
     },
     {
-        0x92D1, "GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS",
+        0x92D1,
+        "GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS",
     },
     {
-        0x92D2, "GL_MAX_VERTEX_ATOMIC_COUNTERS",
+        0x92D2,
+        "GL_MAX_VERTEX_ATOMIC_COUNTERS",
     },
     {
-        0x92D3, "GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES",
+        0x92D3,
+        "GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_OES",
     },
     {
-        0x92D4, "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES",
+        0x92D4,
+        "GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_OES",
     },
     {
-        0x92D5, "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES",
+        0x92D5,
+        "GL_MAX_GEOMETRY_ATOMIC_COUNTERS_OES",
     },
     {
-        0x92D6, "GL_MAX_FRAGMENT_ATOMIC_COUNTERS",
+        0x92D6,
+        "GL_MAX_FRAGMENT_ATOMIC_COUNTERS",
     },
     {
-        0x92D7, "GL_MAX_COMBINED_ATOMIC_COUNTERS",
+        0x92D7,
+        "GL_MAX_COMBINED_ATOMIC_COUNTERS",
     },
     {
-        0x92D8, "GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE",
+        0x92D8,
+        "GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE",
     },
     {
-        0x92D9, "GL_ACTIVE_ATOMIC_COUNTER_BUFFERS",
+        0x92D9,
+        "GL_ACTIVE_ATOMIC_COUNTER_BUFFERS",
     },
     {
-        0x92DB, "GL_UNSIGNED_INT_ATOMIC_COUNTER",
+        0x92DB,
+        "GL_UNSIGNED_INT_ATOMIC_COUNTER",
     },
     {
-        0x92DC, "GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS",
+        0x92DC,
+        "GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS",
     },
     {
-        0x92DD, "GL_FRAGMENT_COVERAGE_TO_COLOR_NV",
+        0x92DD,
+        "GL_FRAGMENT_COVERAGE_TO_COLOR_NV",
     },
     {
-        0x92DE, "GL_FRAGMENT_COVERAGE_COLOR_NV",
+        0x92DE,
+        "GL_FRAGMENT_COVERAGE_COLOR_NV",
     },
     {
-        0x92E0, "GL_DEBUG_OUTPUT_KHR",
+        0x92E0,
+        "GL_DEBUG_OUTPUT_KHR",
     },
     {
-        0x92E1, "GL_UNIFORM",
+        0x92E1,
+        "GL_UNIFORM",
     },
     {
-        0x92E2, "GL_UNIFORM_BLOCK",
+        0x92E2,
+        "GL_UNIFORM_BLOCK",
     },
     {
-        0x92E3, "GL_PROGRAM_INPUT",
+        0x92E3,
+        "GL_PROGRAM_INPUT",
     },
     {
-        0x92E4, "GL_PROGRAM_OUTPUT",
+        0x92E4,
+        "GL_PROGRAM_OUTPUT",
     },
     {
-        0x92E5, "GL_BUFFER_VARIABLE",
+        0x92E5,
+        "GL_BUFFER_VARIABLE",
     },
     {
-        0x92E6, "GL_SHADER_STORAGE_BLOCK",
+        0x92E6,
+        "GL_SHADER_STORAGE_BLOCK",
     },
     {
-        0x92E7, "GL_IS_PER_PATCH_OES",
+        0x92E7,
+        "GL_IS_PER_PATCH_OES",
     },
     {
-        0x92F4, "GL_TRANSFORM_FEEDBACK_VARYING",
+        0x92F4,
+        "GL_TRANSFORM_FEEDBACK_VARYING",
     },
     {
-        0x92F5, "GL_ACTIVE_RESOURCES",
+        0x92F5,
+        "GL_ACTIVE_RESOURCES",
     },
     {
-        0x92F6, "GL_MAX_NAME_LENGTH",
+        0x92F6,
+        "GL_MAX_NAME_LENGTH",
     },
     {
-        0x92F7, "GL_MAX_NUM_ACTIVE_VARIABLES",
+        0x92F7,
+        "GL_MAX_NUM_ACTIVE_VARIABLES",
     },
     {
-        0x92F9, "GL_NAME_LENGTH",
+        0x92F9,
+        "GL_NAME_LENGTH",
     },
     {
-        0x92FA, "GL_TYPE",
+        0x92FA,
+        "GL_TYPE",
     },
     {
-        0x92FB, "GL_ARRAY_SIZE",
+        0x92FB,
+        "GL_ARRAY_SIZE",
     },
     {
-        0x92FC, "GL_OFFSET",
+        0x92FC,
+        "GL_OFFSET",
     },
     {
-        0x92FD, "GL_BLOCK_INDEX",
+        0x92FD,
+        "GL_BLOCK_INDEX",
     },
     {
-        0x92FE, "GL_ARRAY_STRIDE",
+        0x92FE,
+        "GL_ARRAY_STRIDE",
     },
     {
-        0x92FF, "GL_MATRIX_STRIDE",
+        0x92FF,
+        "GL_MATRIX_STRIDE",
     },
     {
-        0x9300, "GL_IS_ROW_MAJOR",
+        0x9300,
+        "GL_IS_ROW_MAJOR",
     },
     {
-        0x9301, "GL_ATOMIC_COUNTER_BUFFER_INDEX",
+        0x9301,
+        "GL_ATOMIC_COUNTER_BUFFER_INDEX",
     },
     {
-        0x9302, "GL_BUFFER_BINDING",
+        0x9302,
+        "GL_BUFFER_BINDING",
     },
     {
-        0x9303, "GL_BUFFER_DATA_SIZE",
+        0x9303,
+        "GL_BUFFER_DATA_SIZE",
     },
     {
-        0x9304, "GL_NUM_ACTIVE_VARIABLES",
+        0x9304,
+        "GL_NUM_ACTIVE_VARIABLES",
     },
     {
-        0x9305, "GL_ACTIVE_VARIABLES",
+        0x9305,
+        "GL_ACTIVE_VARIABLES",
     },
     {
-        0x9306, "GL_REFERENCED_BY_VERTEX_SHADER",
+        0x9306,
+        "GL_REFERENCED_BY_VERTEX_SHADER",
     },
     {
-        0x9307, "GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES",
+        0x9307,
+        "GL_REFERENCED_BY_TESS_CONTROL_SHADER_OES",
     },
     {
-        0x9308, "GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES",
+        0x9308,
+        "GL_REFERENCED_BY_TESS_EVALUATION_SHADER_OES",
     },
     {
-        0x9309, "GL_REFERENCED_BY_GEOMETRY_SHADER_OES",
+        0x9309,
+        "GL_REFERENCED_BY_GEOMETRY_SHADER_OES",
     },
     {
-        0x930A, "GL_REFERENCED_BY_FRAGMENT_SHADER",
+        0x930A,
+        "GL_REFERENCED_BY_FRAGMENT_SHADER",
     },
     {
-        0x930B, "GL_REFERENCED_BY_COMPUTE_SHADER",
+        0x930B,
+        "GL_REFERENCED_BY_COMPUTE_SHADER",
     },
     {
-        0x930C, "GL_TOP_LEVEL_ARRAY_SIZE",
+        0x930C,
+        "GL_TOP_LEVEL_ARRAY_SIZE",
     },
     {
-        0x930D, "GL_TOP_LEVEL_ARRAY_STRIDE",
+        0x930D,
+        "GL_TOP_LEVEL_ARRAY_STRIDE",
     },
     {
-        0x930E, "GL_LOCATION",
+        0x930E,
+        "GL_LOCATION",
     },
     {
-        0x930F, "GL_LOCATION_INDEX_EXT",
+        0x930F,
+        "GL_LOCATION_INDEX_EXT",
     },
     {
-        0x9310, "GL_FRAMEBUFFER_DEFAULT_WIDTH",
+        0x9310,
+        "GL_FRAMEBUFFER_DEFAULT_WIDTH",
     },
     {
-        0x9311, "GL_FRAMEBUFFER_DEFAULT_HEIGHT",
+        0x9311,
+        "GL_FRAMEBUFFER_DEFAULT_HEIGHT",
     },
     {
-        0x9312, "GL_FRAMEBUFFER_DEFAULT_LAYERS_OES",
+        0x9312,
+        "GL_FRAMEBUFFER_DEFAULT_LAYERS_OES",
     },
     {
-        0x9313, "GL_FRAMEBUFFER_DEFAULT_SAMPLES",
+        0x9313,
+        "GL_FRAMEBUFFER_DEFAULT_SAMPLES",
     },
     {
-        0x9314, "GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS",
+        0x9314,
+        "GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS",
     },
     {
-        0x9315, "GL_MAX_FRAMEBUFFER_WIDTH",
+        0x9315,
+        "GL_MAX_FRAMEBUFFER_WIDTH",
     },
     {
-        0x9316, "GL_MAX_FRAMEBUFFER_HEIGHT",
+        0x9316,
+        "GL_MAX_FRAMEBUFFER_HEIGHT",
     },
     {
-        0x9317, "GL_MAX_FRAMEBUFFER_LAYERS_OES",
+        0x9317,
+        "GL_MAX_FRAMEBUFFER_LAYERS_OES",
     },
     {
-        0x9318, "GL_MAX_FRAMEBUFFER_SAMPLES",
+        0x9318,
+        "GL_MAX_FRAMEBUFFER_SAMPLES",
     },
     {
-        0x9327, "GL_RASTER_MULTISAMPLE_EXT",
+        0x9327,
+        "GL_RASTER_MULTISAMPLE_EXT",
     },
     {
-        0x9328, "GL_RASTER_SAMPLES_EXT",
+        0x9328,
+        "GL_RASTER_SAMPLES_EXT",
     },
     {
-        0x9329, "GL_MAX_RASTER_SAMPLES_EXT",
+        0x9329,
+        "GL_MAX_RASTER_SAMPLES_EXT",
     },
     {
-        0x932A, "GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT",
+        0x932A,
+        "GL_RASTER_FIXED_SAMPLE_LOCATIONS_EXT",
     },
     {
-        0x932B, "GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT",
+        0x932B,
+        "GL_MULTISAMPLE_RASTERIZATION_ALLOWED_EXT",
     },
     {
-        0x932C, "GL_EFFECTIVE_RASTER_SAMPLES_EXT",
+        0x932C,
+        "GL_EFFECTIVE_RASTER_SAMPLES_EXT",
     },
     {
-        0x932D, "GL_DEPTH_SAMPLES_NV",
+        0x932D,
+        "GL_DEPTH_SAMPLES_NV",
     },
     {
-        0x932E, "GL_STENCIL_SAMPLES_NV",
+        0x932E,
+        "GL_STENCIL_SAMPLES_NV",
     },
     {
-        0x932F, "GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV",
+        0x932F,
+        "GL_MIXED_DEPTH_SAMPLES_SUPPORTED_NV",
     },
     {
-        0x9330, "GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV",
+        0x9330,
+        "GL_MIXED_STENCIL_SAMPLES_SUPPORTED_NV",
     },
     {
-        0x9331, "GL_COVERAGE_MODULATION_TABLE_NV",
+        0x9331,
+        "GL_COVERAGE_MODULATION_TABLE_NV",
     },
     {
-        0x9332, "GL_COVERAGE_MODULATION_NV",
+        0x9332,
+        "GL_COVERAGE_MODULATION_NV",
     },
     {
-        0x9333, "GL_COVERAGE_MODULATION_TABLE_SIZE_NV",
+        0x9333,
+        "GL_COVERAGE_MODULATION_TABLE_SIZE_NV",
     },
     {
-        0x933C, "GL_FILL_RECTANGLE_NV",
+        0x933C,
+        "GL_FILL_RECTANGLE_NV",
     },
     {
-        0x933D, "GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV",
+        0x933D,
+        "GL_SAMPLE_LOCATION_SUBPIXEL_BITS_NV",
     },
     {
-        0x933E, "GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV",
+        0x933E,
+        "GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_NV",
     },
     {
-        0x933F, "GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV",
+        0x933F,
+        "GL_SAMPLE_LOCATION_PIXEL_GRID_HEIGHT_NV",
     },
     {
-        0x9340, "GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV",
+        0x9340,
+        "GL_PROGRAMMABLE_SAMPLE_LOCATION_TABLE_SIZE_NV",
     },
     {
-        0x9341, "GL_PROGRAMMABLE_SAMPLE_LOCATION_NV",
+        0x9341,
+        "GL_PROGRAMMABLE_SAMPLE_LOCATION_NV",
     },
     {
-        0x9342, "GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV",
+        0x9342,
+        "GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_NV",
     },
     {
-        0x9343, "GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV",
+        0x9343,
+        "GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_NV",
     },
     {
-        0x9346, "GL_CONSERVATIVE_RASTERIZATION_NV",
+        0x9346,
+        "GL_CONSERVATIVE_RASTERIZATION_NV",
     },
     {
-        0x9347, "GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV",
+        0x9347,
+        "GL_SUBPIXEL_PRECISION_BIAS_X_BITS_NV",
     },
     {
-        0x9348, "GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV",
+        0x9348,
+        "GL_SUBPIXEL_PRECISION_BIAS_Y_BITS_NV",
     },
     {
-        0x9349, "GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV",
+        0x9349,
+        "GL_MAX_SUBPIXEL_PRECISION_BIAS_BITS_NV",
     },
     {
-        0x9350, "GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV",
+        0x9350,
+        "GL_VIEWPORT_SWIZZLE_POSITIVE_X_NV",
     },
     {
-        0x9351, "GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV",
+        0x9351,
+        "GL_VIEWPORT_SWIZZLE_NEGATIVE_X_NV",
     },
     {
-        0x9352, "GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV",
+        0x9352,
+        "GL_VIEWPORT_SWIZZLE_POSITIVE_Y_NV",
     },
     {
-        0x9353, "GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV",
+        0x9353,
+        "GL_VIEWPORT_SWIZZLE_NEGATIVE_Y_NV",
     },
     {
-        0x9354, "GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV",
+        0x9354,
+        "GL_VIEWPORT_SWIZZLE_POSITIVE_Z_NV",
     },
     {
-        0x9355, "GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV",
+        0x9355,
+        "GL_VIEWPORT_SWIZZLE_NEGATIVE_Z_NV",
     },
     {
-        0x9356, "GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV",
+        0x9356,
+        "GL_VIEWPORT_SWIZZLE_POSITIVE_W_NV",
     },
     {
-        0x9357, "GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV",
+        0x9357,
+        "GL_VIEWPORT_SWIZZLE_NEGATIVE_W_NV",
     },
     {
-        0x9358, "GL_VIEWPORT_SWIZZLE_X_NV",
+        0x9358,
+        "GL_VIEWPORT_SWIZZLE_X_NV",
     },
     {
-        0x9359, "GL_VIEWPORT_SWIZZLE_Y_NV",
+        0x9359,
+        "GL_VIEWPORT_SWIZZLE_Y_NV",
     },
     {
-        0x935A, "GL_VIEWPORT_SWIZZLE_Z_NV",
+        0x935A,
+        "GL_VIEWPORT_SWIZZLE_Z_NV",
     },
     {
-        0x935B, "GL_VIEWPORT_SWIZZLE_W_NV",
+        0x935B,
+        "GL_VIEWPORT_SWIZZLE_W_NV",
     },
     {
-        0x935C, "GL_CLIP_ORIGIN_EXT",
+        0x935C,
+        "GL_CLIP_ORIGIN_EXT",
     },
     {
-        0x935D, "GL_CLIP_DEPTH_MODE_EXT",
+        0x935D,
+        "GL_CLIP_DEPTH_MODE_EXT",
     },
     {
-        0x935E, "GL_NEGATIVE_ONE_TO_ONE_EXT",
+        0x935E,
+        "GL_NEGATIVE_ONE_TO_ONE_EXT",
     },
     {
-        0x935F, "GL_ZERO_TO_ONE_EXT",
+        0x935F,
+        "GL_ZERO_TO_ONE_EXT",
     },
     {
-        0x9366, "GL_TEXTURE_REDUCTION_MODE_EXT",
+        0x9366,
+        "GL_TEXTURE_REDUCTION_MODE_EXT",
     },
     {
-        0x9367, "GL_WEIGHTED_AVERAGE_EXT",
+        0x9367,
+        "GL_WEIGHTED_AVERAGE_EXT",
     },
     {
-        0x9368, "GL_FONT_GLYPHS_AVAILABLE_NV",
+        0x9368,
+        "GL_FONT_GLYPHS_AVAILABLE_NV",
     },
     {
-        0x9369, "GL_FONT_TARGET_UNAVAILABLE_NV",
+        0x9369,
+        "GL_FONT_TARGET_UNAVAILABLE_NV",
     },
     {
-        0x936A, "GL_FONT_UNAVAILABLE_NV",
+        0x936A,
+        "GL_FONT_UNAVAILABLE_NV",
     },
     {
-        0x936B, "GL_FONT_UNINTELLIGIBLE_NV",
+        0x936B,
+        "GL_FONT_UNINTELLIGIBLE_NV",
     },
     {
-        0x936C, "GL_STANDARD_FONT_FORMAT_NV",
+        0x936C,
+        "GL_STANDARD_FONT_FORMAT_NV",
     },
     {
-        0x936D, "GL_FRAGMENT_INPUT_NV",
+        0x936D,
+        "GL_FRAGMENT_INPUT_NV",
     },
     {
-        0x9371, "GL_MULTISAMPLES_NV",
+        0x9371,
+        "GL_MULTISAMPLES_NV",
     },
     {
-        0x9372, "GL_SUPERSAMPLE_SCALE_X_NV",
+        0x9372,
+        "GL_SUPERSAMPLE_SCALE_X_NV",
     },
     {
-        0x9373, "GL_SUPERSAMPLE_SCALE_Y_NV",
+        0x9373,
+        "GL_SUPERSAMPLE_SCALE_Y_NV",
     },
     {
-        0x9374, "GL_CONFORMANT_NV",
+        0x9374,
+        "GL_CONFORMANT_NV",
     },
     {
-        0x937C, "GL_VIEWPORT_POSITION_W_SCALE_NV",
+        0x937C,
+        "GL_VIEWPORT_POSITION_W_SCALE_NV",
     },
     {
-        0x937D, "GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV",
+        0x937D,
+        "GL_VIEWPORT_POSITION_W_SCALE_X_COEFF_NV",
     },
     {
-        0x937E, "GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV",
+        0x937E,
+        "GL_VIEWPORT_POSITION_W_SCALE_Y_COEFF_NV",
     },
     {
-        0x9380, "GL_NUM_SAMPLE_COUNTS",
+        0x9380,
+        "GL_NUM_SAMPLE_COUNTS",
     },
     {
-        0x93A0, "GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE",
+        0x93A0,
+        "GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE",
     },
     {
-        0x93A1, "GL_BGRA8_EXT",
+        0x93A1,
+        "GL_BGRA8_EXT",
     },
     {
-        0x93A2, "GL_TEXTURE_USAGE_ANGLE",
+        0x93A2,
+        "GL_TEXTURE_USAGE_ANGLE",
     },
     {
-        0x93A3, "GL_FRAMEBUFFER_ATTACHMENT_ANGLE",
+        0x93A3,
+        "GL_FRAMEBUFFER_ATTACHMENT_ANGLE",
     },
     {
-        0x93A4, "GL_PACK_REVERSE_ROW_ORDER_ANGLE",
+        0x93A4,
+        "GL_PACK_REVERSE_ROW_ORDER_ANGLE",
     },
     {
-        0x93A6, "GL_PROGRAM_BINARY_ANGLE",
+        0x93A6,
+        "GL_PROGRAM_BINARY_ANGLE",
     },
     {
-        0x93B0, "GL_COMPRESSED_RGBA_ASTC_4x4_KHR",
+        0x93B0,
+        "GL_COMPRESSED_RGBA_ASTC_4x4_KHR",
     },
     {
-        0x93B1, "GL_COMPRESSED_RGBA_ASTC_5x4_KHR",
+        0x93B1,
+        "GL_COMPRESSED_RGBA_ASTC_5x4_KHR",
     },
     {
-        0x93B2, "GL_COMPRESSED_RGBA_ASTC_5x5_KHR",
+        0x93B2,
+        "GL_COMPRESSED_RGBA_ASTC_5x5_KHR",
     },
     {
-        0x93B3, "GL_COMPRESSED_RGBA_ASTC_6x5_KHR",
+        0x93B3,
+        "GL_COMPRESSED_RGBA_ASTC_6x5_KHR",
     },
     {
-        0x93B4, "GL_COMPRESSED_RGBA_ASTC_6x6_KHR",
+        0x93B4,
+        "GL_COMPRESSED_RGBA_ASTC_6x6_KHR",
     },
     {
-        0x93B5, "GL_COMPRESSED_RGBA_ASTC_8x5_KHR",
+        0x93B5,
+        "GL_COMPRESSED_RGBA_ASTC_8x5_KHR",
     },
     {
-        0x93B6, "GL_COMPRESSED_RGBA_ASTC_8x6_KHR",
+        0x93B6,
+        "GL_COMPRESSED_RGBA_ASTC_8x6_KHR",
     },
     {
-        0x93B7, "GL_COMPRESSED_RGBA_ASTC_8x8_KHR",
+        0x93B7,
+        "GL_COMPRESSED_RGBA_ASTC_8x8_KHR",
     },
     {
-        0x93B8, "GL_COMPRESSED_RGBA_ASTC_10x5_KHR",
+        0x93B8,
+        "GL_COMPRESSED_RGBA_ASTC_10x5_KHR",
     },
     {
-        0x93B9, "GL_COMPRESSED_RGBA_ASTC_10x6_KHR",
+        0x93B9,
+        "GL_COMPRESSED_RGBA_ASTC_10x6_KHR",
     },
     {
-        0x93BA, "GL_COMPRESSED_RGBA_ASTC_10x8_KHR",
+        0x93BA,
+        "GL_COMPRESSED_RGBA_ASTC_10x8_KHR",
     },
     {
-        0x93BB, "GL_COMPRESSED_RGBA_ASTC_10x10_KHR",
+        0x93BB,
+        "GL_COMPRESSED_RGBA_ASTC_10x10_KHR",
     },
     {
-        0x93BC, "GL_COMPRESSED_RGBA_ASTC_12x10_KHR",
+        0x93BC,
+        "GL_COMPRESSED_RGBA_ASTC_12x10_KHR",
     },
     {
-        0x93BD, "GL_COMPRESSED_RGBA_ASTC_12x12_KHR",
+        0x93BD,
+        "GL_COMPRESSED_RGBA_ASTC_12x12_KHR",
     },
     {
-        0x93C0, "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES",
+        0x93C0,
+        "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES",
     },
     {
-        0x93C1, "GL_COMPRESSED_RGBA_ASTC_4x3x3_OES",
+        0x93C1,
+        "GL_COMPRESSED_RGBA_ASTC_4x3x3_OES",
     },
     {
-        0x93C2, "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES",
+        0x93C2,
+        "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES",
     },
     {
-        0x93C3, "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES",
+        0x93C3,
+        "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES",
     },
     {
-        0x93C4, "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES",
+        0x93C4,
+        "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES",
     },
     {
-        0x93C5, "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES",
+        0x93C5,
+        "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES",
     },
     {
-        0x93C6, "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES",
+        0x93C6,
+        "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES",
     },
     {
-        0x93C7, "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES",
+        0x93C7,
+        "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES",
     },
     {
-        0x93C8, "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES",
+        0x93C8,
+        "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES",
     },
     {
-        0x93C9, "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES",
+        0x93C9,
+        "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES",
     },
     {
-        0x93D0, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",
+        0x93D0,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR",
     },
     {
-        0x93D1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",
+        0x93D1,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR",
     },
     {
-        0x93D2, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",
+        0x93D2,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR",
     },
     {
-        0x93D3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",
+        0x93D3,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR",
     },
     {
-        0x93D4, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",
+        0x93D4,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR",
     },
     {
-        0x93D5, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",
+        0x93D5,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR",
     },
     {
-        0x93D6, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",
+        0x93D6,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR",
     },
     {
-        0x93D7, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",
+        0x93D7,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR",
     },
     {
-        0x93D8, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",
+        0x93D8,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR",
     },
     {
-        0x93D9, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",
+        0x93D9,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR",
     },
     {
-        0x93DA, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",
+        0x93DA,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR",
     },
     {
-        0x93DB, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",
+        0x93DB,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR",
     },
     {
-        0x93DC, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR",
+        0x93DC,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR",
     },
     {
-        0x93DD, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",
+        0x93DD,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR",
     },
     {
-        0x93E0, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES",
+        0x93E0,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES",
     },
     {
-        0x93E1, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES",
+        0x93E1,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES",
     },
     {
-        0x93E2, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES",
+        0x93E2,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES",
     },
     {
-        0x93E3, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES",
+        0x93E3,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES",
     },
     {
-        0x93E4, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES",
+        0x93E4,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES",
     },
     {
-        0x93E5, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES",
+        0x93E5,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES",
     },
     {
-        0x93E6, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES",
+        0x93E6,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES",
     },
     {
-        0x93E7, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES",
+        0x93E7,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES",
     },
     {
-        0x93E8, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES",
+        0x93E8,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES",
     },
     {
-        0x93E9, "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES",
+        0x93E9,
+        "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES",
     },
     {
-        0x93F0, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG",
+        0x93F0,
+        "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG",
     },
     {
-        0x93F1, "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG",
+        0x93F1,
+        "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG",
     },
     {
-        0x94F0, "GL_PERFQUERY_COUNTER_EVENT_INTEL",
+        0x94F0,
+        "GL_PERFQUERY_COUNTER_EVENT_INTEL",
     },
     {
-        0x94F1, "GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL",
+        0x94F1,
+        "GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL",
     },
     {
-        0x94F2, "GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL",
+        0x94F2,
+        "GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL",
     },
     {
-        0x94F3, "GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL",
+        0x94F3,
+        "GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL",
     },
     {
-        0x94F4, "GL_PERFQUERY_COUNTER_RAW_INTEL",
+        0x94F4,
+        "GL_PERFQUERY_COUNTER_RAW_INTEL",
     },
     {
-        0x94F5, "GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL",
+        0x94F5,
+        "GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL",
     },
     {
-        0x94F8, "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL",
+        0x94F8,
+        "GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL",
     },
     {
-        0x94F9, "GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL",
+        0x94F9,
+        "GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL",
     },
     {
-        0x94FA, "GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL",
+        0x94FA,
+        "GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL",
     },
     {
-        0x94FB, "GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL",
+        0x94FB,
+        "GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL",
     },
     {
-        0x94FC, "GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL",
+        0x94FC,
+        "GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL",
     },
     {
-        0x94FD, "GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL",
+        0x94FD,
+        "GL_PERFQUERY_QUERY_NAME_LENGTH_MAX_INTEL",
     },
     {
-        0x94FE, "GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL",
+        0x94FE,
+        "GL_PERFQUERY_COUNTER_NAME_LENGTH_MAX_INTEL",
     },
     {
-        0x94FF, "GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL",
+        0x94FF,
+        "GL_PERFQUERY_COUNTER_DESC_LENGTH_MAX_INTEL",
     },
     {
-        0x9500, "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL",
+        0x9500,
+        "GL_PERFQUERY_GPA_EXTENDED_COUNTERS_INTEL",
     },
     {
-        0x9530, "GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT",
+        0x9530,
+        "GL_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_EXT",
     },
     {
-        0x9531, "GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT",
+        0x9531,
+        "GL_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_EXT",
     },
     {
-        0x954D, "GL_CONSERVATIVE_RASTER_MODE_NV",
+        0x954D,
+        "GL_CONSERVATIVE_RASTER_MODE_NV",
     },
     {
-        0x954E, "GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV",
+        0x954E,
+        "GL_CONSERVATIVE_RASTER_MODE_POST_SNAP_NV",
     },
     {
-        0x954F, "GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV",
+        0x954F,
+        "GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_TRIANGLES_NV",
     },
     {
-        0x9550, "GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV",
+        0x9550,
+        "GL_CONSERVATIVE_RASTER_MODE_PRE_SNAP_NV",
     },
     {
-        0x9580, "GL_TEXTURE_TILING_EXT",
+        0x9580,
+        "GL_TEXTURE_TILING_EXT",
     },
     {
-        0x9581, "GL_DEDICATED_MEMORY_OBJECT_EXT",
+        0x9581,
+        "GL_DEDICATED_MEMORY_OBJECT_EXT",
     },
     {
-        0x9582, "GL_NUM_TILING_TYPES_EXT",
+        0x9582,
+        "GL_NUM_TILING_TYPES_EXT",
     },
     {
-        0x9583, "GL_TILING_TYPES_EXT",
+        0x9583,
+        "GL_TILING_TYPES_EXT",
     },
     {
-        0x9584, "GL_OPTIMAL_TILING_EXT",
+        0x9584,
+        "GL_OPTIMAL_TILING_EXT",
     },
     {
-        0x9585, "GL_LINEAR_TILING_EXT",
+        0x9585,
+        "GL_LINEAR_TILING_EXT",
     },
     {
-        0x9586, "GL_HANDLE_TYPE_OPAQUE_FD_EXT",
+        0x9586,
+        "GL_HANDLE_TYPE_OPAQUE_FD_EXT",
     },
     {
-        0x9587, "GL_HANDLE_TYPE_OPAQUE_WIN32_EXT",
+        0x9587,
+        "GL_HANDLE_TYPE_OPAQUE_WIN32_EXT",
     },
     {
-        0x9588, "GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT",
+        0x9588,
+        "GL_HANDLE_TYPE_OPAQUE_WIN32_KMT_EXT",
     },
     {
-        0x9589, "GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT",
+        0x9589,
+        "GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT",
     },
     {
-        0x958A, "GL_HANDLE_TYPE_D3D12_RESOURCE_EXT",
+        0x958A,
+        "GL_HANDLE_TYPE_D3D12_RESOURCE_EXT",
     },
     {
-        0x958B, "GL_HANDLE_TYPE_D3D11_IMAGE_EXT",
+        0x958B,
+        "GL_HANDLE_TYPE_D3D11_IMAGE_EXT",
     },
     {
-        0x958C, "GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT",
+        0x958C,
+        "GL_HANDLE_TYPE_D3D11_IMAGE_KMT_EXT",
     },
     {
-        0x958D, "GL_LAYOUT_GENERAL_EXT",
+        0x958D,
+        "GL_LAYOUT_GENERAL_EXT",
     },
     {
-        0x958E, "GL_LAYOUT_COLOR_ATTACHMENT_EXT",
+        0x958E,
+        "GL_LAYOUT_COLOR_ATTACHMENT_EXT",
     },
     {
-        0x958F, "GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT",
+        0x958F,
+        "GL_LAYOUT_DEPTH_STENCIL_ATTACHMENT_EXT",
     },
     {
-        0x9590, "GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT",
+        0x9590,
+        "GL_LAYOUT_DEPTH_STENCIL_READ_ONLY_EXT",
     },
     {
-        0x9591, "GL_LAYOUT_SHADER_READ_ONLY_EXT",
+        0x9591,
+        "GL_LAYOUT_SHADER_READ_ONLY_EXT",
     },
     {
-        0x9592, "GL_LAYOUT_TRANSFER_SRC_EXT",
+        0x9592,
+        "GL_LAYOUT_TRANSFER_SRC_EXT",
     },
     {
-        0x9593, "GL_LAYOUT_TRANSFER_DST_EXT",
+        0x9593,
+        "GL_LAYOUT_TRANSFER_DST_EXT",
     },
     {
-        0x9594, "GL_HANDLE_TYPE_D3D12_FENCE_EXT",
+        0x9594,
+        "GL_HANDLE_TYPE_D3D12_FENCE_EXT",
     },
     {
-        0x9595, "GL_D3D12_FENCE_VALUE_EXT",
+        0x9595,
+        "GL_D3D12_FENCE_VALUE_EXT",
     },
     {
-        0x9596, "GL_NUM_DEVICE_UUIDS_EXT",
+        0x9596,
+        "GL_NUM_DEVICE_UUIDS_EXT",
     },
     {
-        0x9597, "GL_DEVICE_UUID_EXT",
+        0x9597,
+        "GL_DEVICE_UUID_EXT",
     },
     {
-        0x9598, "GL_DRIVER_UUID_EXT",
+        0x9598,
+        "GL_DRIVER_UUID_EXT",
     },
     {
-        0x9599, "GL_DEVICE_LUID_EXT",
+        0x9599,
+        "GL_DEVICE_LUID_EXT",
     },
     {
-        0x959A, "GL_DEVICE_NODE_MASK_EXT",
+        0x959A,
+        "GL_DEVICE_NODE_MASK_EXT",
     },
     {
-        0x959B, "GL_PROTECTED_MEMORY_OBJECT_EXT",
+        0x959B,
+        "GL_PROTECTED_MEMORY_OBJECT_EXT",
     },
     {
-        0x9630, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR",
+        0x9630,
+        "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR",
     },
     {
-        0x9631, "GL_MAX_VIEWS_OVR",
+        0x9631,
+        "GL_MAX_VIEWS_OVR",
     },
     {
-        0x9632, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR",
+        0x9632,
+        "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR",
     },
     {
-        0x9633, "GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR",
+        0x9633,
+        "GL_FRAMEBUFFER_INCOMPLETE_VIEW_TARGETS_OVR",
     },
     {
-        0x9650, "GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT",
+        0x9650,
+        "GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_FAST_SIZE_EXT",
     },
     {
-        0x9651, "GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT",
+        0x9651,
+        "GL_MAX_SHADER_COMBINED_LOCAL_STORAGE_SIZE_EXT",
     },
     {
         0x9652,
@@ -4860,67 +6474,88 @@
         "EXT",
     },
     {
-        0x96A2, "GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM",
+        0x96A2,
+        "GL_FRAMEBUFFER_FETCH_NONCOHERENT_QCOM",
     },
     {
-        0xC0, "GL_SHARED_EDGE_NV",
+        0xC0,
+        "GL_SHARED_EDGE_NV",
     },
     {
-        0xE8, "GL_ROUNDED_RECT_NV",
+        0xE8,
+        "GL_ROUNDED_RECT_NV",
     },
     {
-        0xE9, "GL_RELATIVE_ROUNDED_RECT_NV",
+        0xE9,
+        "GL_RELATIVE_ROUNDED_RECT_NV",
     },
     {
-        0xEA, "GL_ROUNDED_RECT2_NV",
+        0xEA,
+        "GL_ROUNDED_RECT2_NV",
     },
     {
-        0xEB, "GL_RELATIVE_ROUNDED_RECT2_NV",
+        0xEB,
+        "GL_RELATIVE_ROUNDED_RECT2_NV",
     },
     {
-        0xEC, "GL_ROUNDED_RECT4_NV",
+        0xEC,
+        "GL_ROUNDED_RECT4_NV",
     },
     {
-        0xED, "GL_RELATIVE_ROUNDED_RECT4_NV",
+        0xED,
+        "GL_RELATIVE_ROUNDED_RECT4_NV",
     },
     {
-        0xEE, "GL_ROUNDED_RECT8_NV",
+        0xEE,
+        "GL_ROUNDED_RECT8_NV",
     },
     {
-        0xEF, "GL_RELATIVE_ROUNDED_RECT8_NV",
+        0xEF,
+        "GL_RELATIVE_ROUNDED_RECT8_NV",
     },
     {
-        0xF0, "GL_RESTART_PATH_NV",
+        0xF0,
+        "GL_RESTART_PATH_NV",
     },
     {
-        0xF2, "GL_DUP_FIRST_CUBIC_CURVE_TO_NV",
+        0xF2,
+        "GL_DUP_FIRST_CUBIC_CURVE_TO_NV",
     },
     {
-        0xF4, "GL_DUP_LAST_CUBIC_CURVE_TO_NV",
+        0xF4,
+        "GL_DUP_LAST_CUBIC_CURVE_TO_NV",
     },
     {
-        0xF6, "GL_RECT_NV",
+        0xF6,
+        "GL_RECT_NV",
     },
     {
-        0xF7, "GL_RELATIVE_RECT_NV",
+        0xF7,
+        "GL_RELATIVE_RECT_NV",
     },
     {
-        0xF8, "GL_CIRCULAR_CCW_ARC_TO_NV",
+        0xF8,
+        "GL_CIRCULAR_CCW_ARC_TO_NV",
     },
     {
-        0xFA, "GL_CIRCULAR_CW_ARC_TO_NV",
+        0xFA,
+        "GL_CIRCULAR_CW_ARC_TO_NV",
     },
     {
-        0xFC, "GL_CIRCULAR_TANGENT_ARC_TO_NV",
+        0xFC,
+        "GL_CIRCULAR_TANGENT_ARC_TO_NV",
     },
     {
-        0xFE, "GL_ARC_TO_NV",
+        0xFE,
+        "GL_ARC_TO_NV",
     },
     {
-        0xFF, "GL_RELATIVE_ARC_TO_NV",
+        0xFF,
+        "GL_RELATIVE_ARC_TO_NV",
     },
     {
-        0xFFFFFFFF, "GL_ALL_SHADER_BITS_EXT",
+        0xFFFFFFFF,
+        "GL_ALL_SHADER_BITS_EXT",
     },
 };
 
diff --git a/ui/gl/gl_mock_autogen_egl.h b/ui/gl/gl_mock_autogen_egl.h
index fac8c31..a8b2b6c 100644
--- a/ui/gl/gl_mock_autogen_egl.h
+++ b/ui/gl/gl_mock_autogen_egl.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 MOCK_METHOD1(BindAPI, EGLBoolean(EGLenum api));
 MOCK_METHOD3(BindTexImage,
diff --git a/ui/gl/gl_mock_autogen_gl.h b/ui/gl/gl_mock_autogen_gl.h
index 534700d..a0dcae6 100644
--- a/ui/gl/gl_mock_autogen_gl.h
+++ b/ui/gl/gl_mock_autogen_gl.h
@@ -8,9 +8,9 @@
 //    clang-format -i -style=chromium filename
 // DO NOT EDIT!
 
-// The following line silences a presubmit warning that would otherwise be
-// triggered by this:
+// Silence presubmit and Tricium warnings about include guards
 // no-include-guard-because-multiply-included
+// NOLINT(build/header_guard)
 
 MOCK_METHOD2(ActiveShaderProgram, void(GLuint pipeline, GLuint program));
 MOCK_METHOD1(ActiveTexture, void(GLenum texture));
@@ -517,6 +517,13 @@
                   GLsizei bufSize,
                   GLsizei* length,
                   GLint* params));
+MOCK_METHOD6(GetInternalformatSampleivNV,
+             void(GLenum target,
+                  GLenum internalformat,
+                  GLsizei samples,
+                  GLenum pname,
+                  GLsizei bufSize,
+                  GLint* params));
 MOCK_METHOD3(GetMultisamplefv, void(GLenum pname, GLuint index, GLfloat* val));
 MOCK_METHOD5(GetMultisamplefvRobustANGLE,
              void(GLenum pname,
diff --git a/ui/gl/gl_stub_autogen_gl.h b/ui/gl/gl_stub_autogen_gl.h
index 32cf931..769f9bfa 100644
--- a/ui/gl/gl_stub_autogen_gl.h
+++ b/ui/gl/gl_stub_autogen_gl.h
@@ -541,6 +541,12 @@
                                         GLsizei bufSize,
                                         GLsizei* length,
                                         GLint* params) override {}
+void glGetInternalformatSampleivNVFn(GLenum target,
+                                     GLenum internalformat,
+                                     GLsizei samples,
+                                     GLenum pname,
+                                     GLsizei bufSize,
+                                     GLint* params) override {}
 void glGetMultisamplefvFn(GLenum pname, GLuint index, GLfloat* val) override {}
 void glGetMultisamplefvRobustANGLEFn(GLenum pname,
                                      GLuint index,
diff --git a/ui/ozone/platform/wayland/BUILD.gn b/ui/ozone/platform/wayland/BUILD.gn
index ddbcee3..47e9bafe 100644
--- a/ui/ozone/platform/wayland/BUILD.gn
+++ b/ui/ozone/platform/wayland/BUILD.gn
@@ -82,10 +82,6 @@
 
   import("//ui/base/ui_features.gni")
   if (use_xkbcommon) {
-    sources += [
-      "wayland_xkb_keyboard_layout_engine.cc",
-      "wayland_xkb_keyboard_layout_engine.h",
-    ]
     configs += [ "//ui/events/ozone:xkbcommon" ]
   }
 
diff --git a/ui/ozone/platform/wayland/ozone_platform_wayland.cc b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
index 7399925e..904f32ff 100644
--- a/ui/ozone/platform/wayland/ozone_platform_wayland.cc
+++ b/ui/ozone/platform/wayland/ozone_platform_wayland.cc
@@ -4,6 +4,11 @@
 
 #include "ui/ozone/platform/wayland/ozone_platform_wayland.h"
 
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
 #include "ui/base/buildflags.h"
@@ -27,7 +32,7 @@
 
 #if BUILDFLAG(USE_XKBCOMMON)
 #include "ui/events/ozone/layout/xkb/xkb_evdev_codes.h"
-#include "ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h"
+#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
 #else
 #include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
 #endif
@@ -140,8 +145,7 @@
   void InitializeUI(const InitParams& args) override {
 #if BUILDFLAG(USE_XKBCOMMON)
     KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
-        std::make_unique<WaylandXkbKeyboardLayoutEngine>(
-            xkb_evdev_code_converter_));
+        std::make_unique<XkbKeyboardLayoutEngine>(xkb_evdev_code_converter_));
 #else
     KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
         std::make_unique<StubKeyboardLayoutEngine>());
diff --git a/ui/ozone/platform/wayland/wayland_connection.cc b/ui/ozone/platform/wayland/wayland_connection.cc
index 1a7882b..3939c1a 100644
--- a/ui/ozone/platform/wayland/wayland_connection.cc
+++ b/ui/ozone/platform/wayland/wayland_connection.cc
@@ -14,6 +14,7 @@
 #include "base/message_loop/message_loop_current.h"
 #include "base/strings/string_util.h"
 #include "base/threading/thread_task_runner_handle.h"
+#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
 #include "ui/gfx/swap_result.h"
 #include "ui/ozone/platform/wayland/wayland_buffer_manager.h"
 #include "ui/ozone/platform/wayland/wayland_input_method_context.h"
@@ -539,8 +540,9 @@
         return;
       }
       connection->keyboard_ = std::make_unique<WaylandKeyboard>(
-          keyboard, base::BindRepeating(&WaylandConnection::DispatchUiEvent,
-                                        base::Unretained(connection)));
+          keyboard, KeyboardLayoutEngineManager::GetKeyboardLayoutEngine(),
+          base::BindRepeating(&WaylandConnection::DispatchUiEvent,
+                              base::Unretained(connection)));
       connection->keyboard_->set_connection(connection);
     }
   } else if (connection->keyboard_) {
diff --git a/ui/ozone/platform/wayland/wayland_keyboard.cc b/ui/ozone/platform/wayland/wayland_keyboard.cc
index a6d0ea7..770908b 100644
--- a/ui/ozone/platform/wayland/wayland_keyboard.cc
+++ b/ui/ozone/platform/wayland/wayland_keyboard.cc
@@ -5,6 +5,7 @@
 #include "ui/ozone/platform/wayland/wayland_keyboard.h"
 
 #include <sys/mman.h>
+#include <utility>
 
 #include "base/files/scoped_file.h"
 #include "ui/base/buildflags.h"
@@ -12,6 +13,7 @@
 #include "ui/events/event.h"
 #include "ui/events/keycodes/dom/dom_code.h"
 #include "ui/events/keycodes/dom/keycode_converter.h"
+#include "ui/events/ozone/evdev/keyboard_util_evdev.h"
 #include "ui/events/ozone/layout/keyboard_layout_engine.h"
 #include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
 #include "ui/events/ozone/layout/layout_util.h"
@@ -19,37 +21,33 @@
 #include "ui/ozone/platform/wayland/wayland_window.h"
 
 #if BUILDFLAG(USE_XKBCOMMON)
-#include "ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h"
+#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
 #endif
 
 namespace ui {
 
-namespace {
-
-const int kXkbKeycodeOffset = 8;
-
-}  // namespace
-
 // static
 const wl_callback_listener WaylandKeyboard::callback_listener_ = {
     WaylandKeyboard::SyncCallback,
 };
 
 WaylandKeyboard::WaylandKeyboard(wl_keyboard* keyboard,
+                                 KeyboardLayoutEngine* layout_engine,
                                  const EventDispatchCallback& callback)
-    : obj_(keyboard), callback_(callback), auto_repeat_handler_(this) {
+    : obj_(keyboard),
+      callback_(callback),
+      auto_repeat_handler_(this),
+#if BUILDFLAG(USE_XKBCOMMON)
+      layout_engine_(static_cast<XkbKeyboardLayoutEngine*>(layout_engine)) {
+#else
+      layout_engine_(layout_engine) {
+#endif
   static const wl_keyboard_listener listener = {
       &WaylandKeyboard::Keymap,    &WaylandKeyboard::Enter,
       &WaylandKeyboard::Leave,     &WaylandKeyboard::Key,
       &WaylandKeyboard::Modifiers, &WaylandKeyboard::RepeatInfo,
   };
 
-#if BUILDFLAG(USE_XKBCOMMON)
-  auto* engine = static_cast<WaylandXkbKeyboardLayoutEngine*>(
-      KeyboardLayoutEngineManager::GetKeyboardLayoutEngine());
-  engine->SetEventModifiers(&event_modifiers_);
-#endif
-
   wl_keyboard_add_listener(obj_.get(), &listener, this);
 
   // TODO(tonikitoo): Default auto-repeat to ON here?
@@ -62,6 +60,9 @@
                              uint32_t format,
                              int32_t raw_fd,
                              uint32_t size) {
+  WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data);
+  DCHECK(keyboard);
+
   base::ScopedFD fd(raw_fd);
   if (!data || format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1)
     return;
@@ -71,9 +72,9 @@
   if (keymap_str == MAP_FAILED)
     return;
 
+  auto length = strnlen(keymap_str, size);
   bool success =
-      KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()
-          ->SetCurrentLayoutFromBuffer(keymap_str, strnlen(keymap_str, size));
+      keyboard->layout_engine_->SetCurrentLayoutFromBuffer(keymap_str, length);
   DCHECK(success) << "Failed to set the XKB keyboard mapping.";
   munmap(keymap_str, size);
 }
@@ -128,14 +129,16 @@
 void WaylandKeyboard::Modifiers(void* data,
                                 wl_keyboard* obj,
                                 uint32_t serial,
-                                uint32_t mods_depressed,
-                                uint32_t mods_latched,
-                                uint32_t mods_locked,
+                                uint32_t depressed,
+                                uint32_t latched,
+                                uint32_t locked,
                                 uint32_t group) {
 #if BUILDFLAG(USE_XKBCOMMON)
-  auto* engine = static_cast<WaylandXkbKeyboardLayoutEngine*>(
-      KeyboardLayoutEngineManager::GetKeyboardLayoutEngine());
-  engine->UpdateModifiers(mods_depressed, mods_latched, mods_locked, group);
+  WaylandKeyboard* keyboard = static_cast<WaylandKeyboard*>(data);
+  DCHECK(keyboard);
+
+  keyboard->modifiers_ = keyboard->layout_engine_->GetModifierFlags(
+      depressed, latched, locked, group);
 #endif
 }
 
@@ -171,15 +174,13 @@
                                   base::TimeTicks timestamp,
                                   int device_id) {
   DomCode dom_code =
-      KeycodeConverter::NativeKeycodeToDomCode(key + kXkbKeycodeOffset);
+      KeycodeConverter::NativeKeycodeToDomCode(EvdevCodeToNativeCode(key));
   if (dom_code == ui::DomCode::NONE)
     return;
 
-  uint8_t flags = event_modifiers_.GetModifierFlags();
   DomKey dom_key;
   KeyboardCode key_code;
-  if (!KeyboardLayoutEngineManager::GetKeyboardLayoutEngine()->Lookup(
-          dom_code, flags, &dom_key, &key_code))
+  if (!layout_engine_->Lookup(dom_code, modifiers_, &dom_key, &key_code))
     return;
 
   if (!repeat) {
@@ -188,8 +189,7 @@
   }
 
   ui::KeyEvent event(down ? ET_KEY_PRESSED : ET_KEY_RELEASED, key_code,
-                     dom_code, event_modifiers_.GetModifierFlags(), dom_key,
-                     timestamp);
+                     dom_code, modifiers_, dom_key, timestamp);
   event.set_source_device_id(device_id);
   callback_.Run(&event);
 }
@@ -205,25 +205,22 @@
   keyboard->sync_callback_.reset();
 }
 
-void WaylandKeyboard::UpdateModifier(int modifier_flag, bool down) {
-  if (modifier_flag == EF_NONE)
+void WaylandKeyboard::UpdateModifier(int modifier, bool down) {
+  if (modifier == EF_NONE)
     return;
 
-  int modifier = EventModifiers::GetModifierFromEventFlag(modifier_flag);
-  if (modifier == MODIFIER_NONE)
-    return;
-
-  // This mimics KeyboardEvDev, which matches chrome/x11.
+  // TODO(nickdiego): ChromeOS-specific keyboard remapping logic.
+  // Remove this once it is properly guarded under OS_CHROMEOS.
+  //
   // Currently EF_MOD3_DOWN means that the CapsLock key is currently down,
   // and EF_CAPS_LOCK_ON means the caps lock state is enabled (and the
   // key may or may not be down, but usually isn't). There does need to
   // to be two different flags, since the physical CapsLock key is subject
   // to remapping, but the caps lock state (which can be triggered in a
   // variety of ways) is not.
-  if (modifier == MODIFIER_CAPS_LOCK)
-    event_modifiers_.UpdateModifier(MODIFIER_MOD3, down);
-  else
-    event_modifiers_.UpdateModifier(modifier, down);
+  if (modifier == EF_CAPS_LOCK_ON)
+    modifier = (modifier & ~EF_CAPS_LOCK_ON) | EF_MOD3_DOWN;
+  modifiers_ = down ? (modifiers_ | modifier) : (modifiers_ & ~modifier);
 }
 
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_keyboard.h b/ui/ozone/platform/wayland/wayland_keyboard.h
index 18b535a..9c4155c 100644
--- a/ui/ozone/platform/wayland/wayland_keyboard.h
+++ b/ui/ozone/platform/wayland/wayland_keyboard.h
@@ -7,25 +7,31 @@
 
 #include <wayland-client.h>
 
-#include "ui/events/event_modifiers.h"
+#include "ui/base/buildflags.h"
 #include "ui/events/ozone/evdev/event_dispatch_callback.h"
 #include "ui/events/ozone/keyboard/event_auto_repeat_handler.h"
 #include "ui/ozone/platform/wayland/wayland_object.h"
 
 namespace ui {
 
+class KeyboardLayoutEngine;
+#if BUILDFLAG(USE_XKBCOMMON)
+class XkbKeyboardLayoutEngine;
+#endif
 class WaylandConnection;
 
 class WaylandKeyboard : public EventAutoRepeatHandler::Delegate {
  public:
-  WaylandKeyboard(wl_keyboard* keyboard, const EventDispatchCallback& callback);
+  WaylandKeyboard(wl_keyboard* keyboard,
+                  KeyboardLayoutEngine* keyboard_layout_engine,
+                  const EventDispatchCallback& callback);
   virtual ~WaylandKeyboard();
 
   void set_connection(WaylandConnection* connection) {
     connection_ = connection;
   }
 
-  int modifiers() { return event_modifiers_.GetModifierFlags(); }
+  int modifiers() { return modifiers_; }
 
  private:
   // wl_keyboard_listener
@@ -63,7 +69,7 @@
 
   static void SyncCallback(void* data, struct wl_callback* cb, uint32_t time);
 
-  void UpdateModifier(int modifier_flag, bool down);
+  void UpdateModifier(int modifier, bool down);
 
   // EventAutoRepeatHandler::Delegate
   void FlushInput(base::OnceClosure closure) override;
@@ -76,13 +82,19 @@
   WaylandConnection* connection_ = nullptr;
   wl::Object<wl_keyboard> obj_;
   EventDispatchCallback callback_;
-  EventModifiers event_modifiers_;
+  int modifiers_ = 0;
 
   // Key repeat handler.
   static const wl_callback_listener callback_listener_;
   EventAutoRepeatHandler auto_repeat_handler_;
   base::OnceClosure auto_repeat_closure_;
   wl::Object<wl_callback> sync_callback_;
+
+#if BUILDFLAG(USE_XKBCOMMON)
+  XkbKeyboardLayoutEngine* layout_engine_;
+#else
+  KeyboardLayoutEngine* layout_engine_;
+#endif
 };
 
 }  // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_test.cc b/ui/ozone/platform/wayland/wayland_test.cc
index 219a2f5..495d6a3 100644
--- a/ui/ozone/platform/wayland/wayland_test.cc
+++ b/ui/ozone/platform/wayland/wayland_test.cc
@@ -10,7 +10,7 @@
 #include "ui/platform_window/platform_window_init_properties.h"
 
 #if BUILDFLAG(USE_XKBCOMMON)
-#include "ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h"
+#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
 #else
 #include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
 #endif
@@ -25,8 +25,7 @@
           base::test::ScopedTaskEnvironment::MainThreadType::UI) {
 #if BUILDFLAG(USE_XKBCOMMON)
   KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
-      std::make_unique<WaylandXkbKeyboardLayoutEngine>(
-          xkb_evdev_code_converter_));
+      std::make_unique<XkbKeyboardLayoutEngine>(xkb_evdev_code_converter_));
 #else
   KeyboardLayoutEngineManager::SetKeyboardLayoutEngine(
       std::make_unique<StubKeyboardLayoutEngine>());
diff --git a/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc b/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc
deleted file mode 100644
index d1865c62..0000000
--- a/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.cc
+++ /dev/null
@@ -1,63 +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 "ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h"
-
-#include "ui/events/event_constants.h"
-#include "ui/events/event_modifiers.h"
-
-namespace ui {
-
-void WaylandXkbKeyboardLayoutEngine::SetKeymap(xkb_keymap* keymap) {
-  XkbKeyboardLayoutEngine::SetKeymap(keymap);
-
-  xkb_mod_indexes_.control =
-      xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CTRL);
-  xkb_mod_indexes_.alt = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_ALT);
-  xkb_mod_indexes_.shift = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_SHIFT);
-  xkb_mod_indexes_.caps = xkb_keymap_mod_get_index(keymap, XKB_MOD_NAME_CAPS);
-  xkb_mod_indexes_.altgr = xkb_keymap_mod_get_index(keymap, "Mod5");
-}
-
-void WaylandXkbKeyboardLayoutEngine::UpdateModifiers(uint32_t depressed_mods,
-                                                     uint32_t latched_mods,
-                                                     uint32_t locked_mods,
-                                                     uint32_t group) {
-  xkb_state_update_mask(xkb_state_.get(), depressed_mods, latched_mods,
-                        locked_mods, 0, 0, group);
-
-  event_modifiers_->ResetKeyboardModifiers();
-
-  auto component = static_cast<xkb_state_component>(XKB_STATE_MODS_DEPRESSED |
-                                                    XKB_STATE_MODS_LATCHED |
-                                                    XKB_STATE_MODS_LOCKED);
-  if (xkb_state_mod_index_is_active(xkb_state_.get(), xkb_mod_indexes_.control,
-                                    component))
-    event_modifiers_->UpdateModifier(MODIFIER_CONTROL, true);
-
-  if (xkb_state_mod_index_is_active(xkb_state_.get(), xkb_mod_indexes_.alt,
-                                    component))
-    event_modifiers_->UpdateModifier(MODIFIER_ALT, true);
-
-  if (xkb_state_mod_index_is_active(xkb_state_.get(), xkb_mod_indexes_.shift,
-                                    component))
-    event_modifiers_->UpdateModifier(MODIFIER_SHIFT, true);
-
-  if (xkb_state_mod_index_is_active(xkb_state_.get(), xkb_mod_indexes_.caps,
-                                    component))
-    event_modifiers_->SetModifierLock(MODIFIER_CAPS_LOCK, true);
-  else
-    event_modifiers_->SetModifierLock(MODIFIER_CAPS_LOCK, false);
-
-  if (xkb_state_mod_index_is_active(xkb_state_.get(), xkb_mod_indexes_.altgr,
-                                    component))
-    event_modifiers_->UpdateModifier(MODIFIER_ALTGR, true);
-}
-
-void WaylandXkbKeyboardLayoutEngine::SetEventModifiers(
-    EventModifiers* event_modifiers) {
-  event_modifiers_ = event_modifiers;
-}
-
-}  // namespace ui
diff --git a/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h b/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h
deleted file mode 100644
index 70bf303..0000000
--- a/ui/ozone/platform/wayland/wayland_xkb_keyboard_layout_engine.h
+++ /dev/null
@@ -1,47 +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 UI_OZONE_PLATFORM_WAYLAND_WAYLAND_XKB_KEYBOARD_LAYOUT_ENGINE_H_
-#define UI_OZONE_PLATFORM_WAYLAND_WAYLAND_XKB_KEYBOARD_LAYOUT_ENGINE_H_
-
-#include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
-
-#include "ui/events/ozone/layout/xkb/xkb_key_code_converter.h"
-
-namespace ui {
-
-class EventModifiers;
-
-class WaylandXkbKeyboardLayoutEngine : public XkbKeyboardLayoutEngine {
- public:
-  WaylandXkbKeyboardLayoutEngine(const XkbKeyCodeConverter& converter)
-      : XkbKeyboardLayoutEngine(converter) {}
-
-  // Used to sync up client side 'xkb_state' instance with modifiers status
-  // update from the compositor.
-  void UpdateModifiers(uint32_t depressed_mods,
-                       uint32_t latched_mods,
-                       uint32_t locked_mods,
-                       uint32_t group);
-
-  void SetEventModifiers(EventModifiers* event_modifiers);
-
- private:
-  void SetKeymap(xkb_keymap* keymap) override;
-
-  // Cache to access modifiers xkb_mode_index_t value.
-  struct {
-    xkb_mod_index_t control = 0;
-    xkb_mod_index_t alt = 0;
-    xkb_mod_index_t shift = 0;
-    xkb_mod_index_t caps = 0;
-    xkb_mod_index_t altgr = 0;
-  } xkb_mod_indexes_;
-
-  EventModifiers* event_modifiers_ = nullptr;  // Owned by WaylandKeyboard.
-};
-
-}  // namespace ui
-
-#endif  // UI_EVENTS_OZONE_LAYOUT_XKB_XKB_KEYBOARD_LAYOUT_ENGINE_H_
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn
index e38d23a..e588264 100644
--- a/ui/views/BUILD.gn
+++ b/ui/views/BUILD.gn
@@ -582,6 +582,7 @@
       "dwmapi.lib",
       "imm32.lib",
       "oleacc.lib",
+      "uiautomationcore.lib",
       "wtsapi32.lib",
     ]
     ldflags = [ "/DELAYLOAD:user32.dll" ]
diff --git a/ui/views/widget/widget_interactive_uitest.cc b/ui/views/widget/widget_interactive_uitest.cc
index d2cf16d1..1a540cc 100644
--- a/ui/views/widget/widget_interactive_uitest.cc
+++ b/ui/views/widget/widget_interactive_uitest.cc
@@ -998,7 +998,6 @@
 }
 #endif  // defined(OS_WIN)
 
-#if !defined(OS_CHROMEOS)
 // Provides functionality to create a window modal dialog.
 class ModalDialogDelegate : public DialogDelegateView {
  public:
@@ -1039,9 +1038,15 @@
   EXPECT_EQ(top_level_native_view, focus_changes[0]);
 
   // Create a modal dialog.
+  ui::ModalType modal_type = ui::MODAL_TYPE_WINDOW;
+#if defined(OS_CHROMEOS)
+  // On Chrome OS this only works for MODAL_TYPE_CHILD, which makes a widget
+  // backed by NativeWidgetAura. Restoring focus to the parent window from a
+  // closed MODAL_TYPE_WINDOW requires help from the window service.
+  modal_type = ui::MODAL_TYPE_CHILD;
+#endif
   // This instance will be destroyed when the dialog is destroyed.
-  ModalDialogDelegate* dialog_delegate =
-      new ModalDialogDelegate(ui::MODAL_TYPE_WINDOW);
+  ModalDialogDelegate* dialog_delegate = new ModalDialogDelegate(modal_type);
 
   Widget* modal_dialog_widget = views::DialogDelegate::CreateDialogWidget(
       dialog_delegate, NULL, top_level_widget.GetNativeView());
@@ -1079,6 +1084,11 @@
 // those.
 #if defined(OS_MACOSX) && !defined(USE_AURA)
 #define MAYBE_SystemModalWindowReleasesCapture \
+  DISABLED_SystemModalWindowReleasesCapture
+#elif defined(OS_CHROMEOS)
+// Investigate enabling for Chrome OS. It probably requires help from the window
+// service.
+#define MAYBE_SystemModalWindowReleasesCapture \
     DISABLED_SystemModalWindowReleasesCapture
 #else
 #define MAYBE_SystemModalWindowReleasesCapture SystemModalWindowReleasesCapture
@@ -1124,8 +1134,6 @@
   WidgetFocusManager::GetInstance()->RemoveFocusChangeListener(&focus_listener);
 }
 
-#endif  // !defined(OS_CHROMEOS)
-
 TEST_F(DesktopWidgetTestInteractive, CanActivateFlagIsHonored) {
   Widget widget;
   Widget::InitParams init_params =
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc
index f3523d2..72dc6646 100644
--- a/ui/views/win/hwnd_message_handler.cc
+++ b/ui/views/win/hwnd_message_handler.cc
@@ -25,6 +25,7 @@
 #include "base/win/scoped_gdi_object.h"
 #include "base/win/windows_version.h"
 #include "third_party/skia/include/core/SkPath.h"
+#include "ui/accessibility/accessibility_switches.h"
 #include "ui/accessibility/platform/ax_platform_node_win.h"
 #include "ui/accessibility/platform/ax_system_caret_win.h"
 #include "ui/base/ime/input_method.h"
@@ -1767,13 +1768,27 @@
   DWORD obj_id = static_cast<DWORD>(static_cast<DWORD_PTR>(l_param));
 
   // Accessibility readers will send an OBJID_CLIENT message
-  if (delegate_->GetNativeViewAccessible() &&
-      static_cast<DWORD>(OBJID_CLIENT) == obj_id) {
-    // Retrieve MSAA dispatch object for the root view.
-    Microsoft::WRL::ComPtr<IAccessible> root(
-        delegate_->GetNativeViewAccessible());
-    reference_result = LresultFromObject(IID_IAccessible, w_param,
-        static_cast<IAccessible*>(root.Detach()));
+  if (delegate_->GetNativeViewAccessible()) {
+    bool is_uia_request = static_cast<DWORD>(UiaRootObjectId) == obj_id;
+    bool is_msaa_request = static_cast<DWORD>(OBJID_CLIENT) == obj_id;
+
+    // Expose either the UIA or the MSAA implementation, but not both, depending
+    // on the state of the feature flag.
+    if (is_uia_request &&
+        ::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
+      // Retrieve UIA object for the root view.
+      Microsoft::WRL::ComPtr<IRawElementProviderSimple> root;
+      delegate_->GetNativeViewAccessible()->QueryInterface(IID_PPV_ARGS(&root));
+      reference_result =
+          UiaReturnRawElementProvider(hwnd(), w_param, l_param, root.Detach());
+    } else if (is_msaa_request &&
+               !::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
+      // Retrieve MSAA dispatch object for the root view.
+      Microsoft::WRL::ComPtr<IAccessible> root(
+          delegate_->GetNativeViewAccessible());
+      reference_result = LresultFromObject(
+          IID_IAccessible, w_param, static_cast<IAccessible*>(root.Detach()));
+    }
   } else if (::GetFocus() == hwnd() && ax_system_caret_ &&
              static_cast<DWORD>(OBJID_CARET) == obj_id) {
     Microsoft::WRL::ComPtr<IAccessible> ax_system_caret_accessible =