diff --git a/DEPS b/DEPS
index c69ab1fb..7dad1b3 100644
--- a/DEPS
+++ b/DEPS
@@ -228,11 +228,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': 'e405d7c8e5e514cdd8f53c019c54d1a65802123f',
+  'skia_revision': '92ae58f33874af1d308ce27dd7df9d029dc858e3',
   # 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': '7cf72e4fda3ebe0221b5e9ff1f0acc63a2454e05',
+  'v8_revision': '7130623b570abb3505aad6e24bec00234d6ae99e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -295,7 +295,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': 'e155ea5c89252285c5c2fc03f4840fe8ef9c1a36',
+  'catapult_revision': '818a24d7bac8e3008f8f43b20cbda61b7addfb25',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -303,7 +303,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': '26cbaf8f7ac558d267caad0258cf0b59ae549265',
+  'devtools_frontend_revision': '13d8667574e82576d5848212f8dbec3b7f77f85b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -343,7 +343,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'e0da9ffedd92d1f6357d37d7d6ab5cf9c5583feb',
+  'dawn_revision': '999cc24209657701e42dd7ef7a2c95be1ad73f2b',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -1290,7 +1290,7 @@
     Var('chromium_git') + '/webm/libwebm.git' + '@' + 'e4fbea0c9751ae8aa86629b197a28d8276a2b0da',
 
   'src/third_party/libyuv':
-    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + '33a68ec7794d6ca897e129d74e425a75a009e156',
+    Var('chromium_git') + '/libyuv/libyuv.git' + '@' + 'b92a60320f6d3021bafe95d7906ad156cb32d611',
 
   'src/third_party/lighttpd': {
       'url': Var('chromium_git') + '/chromium/deps/lighttpd.git' + '@' + Var('lighttpd_revision'),
@@ -1381,7 +1381,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '3dd5b80bc4f172dd82925bb259cb7c82348409c5',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '044f2541032687c14eb10caa2cdaef1f017a46ca',
+    Var('chromium_git') + '/openscreen' + '@' + '5467ac6e5c120051f44720dcd0a0de9be9a52b87',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1476,7 +1476,7 @@
       'packages': [
           {
               'package': 'fuchsia/third_party/aemu/linux-amd64',
-              'version': 'ch1xlBY_IWu7ZT5mlSZqIchzgTLdF1h7juEEoQUjr4cC'
+              'version': '35rwW0ni0eziJ2doq4bSBym86edze8jHjf2fyZhjl8kC'
           },
       ],
       'condition': 'host_os == "linux" and checkout_fuchsia',
@@ -1677,7 +1677,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@92a14c4799524aeb2690040608f3ad9771f81dcb',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@dcb507e9822d05ce2ca6e63e7d4e70d2c075f209',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/android_webview/browser/aw_feature_list_creator.cc b/android_webview/browser/aw_feature_list_creator.cc
index b5dcbdc..684b0aab 100644
--- a/android_webview/browser/aw_feature_list_creator.cc
+++ b/android_webview/browser/aw_feature_list_creator.cc
@@ -18,7 +18,6 @@
 #include "android_webview/browser/variations/variations_seed_loader.h"
 #include "android_webview/common/aw_switches.h"
 #include "android_webview/proto/aw_variations_seed.pb.h"
-#include "base/base_switches.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
@@ -28,7 +27,6 @@
 #include "base/strings/string_split.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
-#include "cc/base/switches.h"
 #include "components/autofill/core/common/autofill_prefs.h"
 #include "components/embedder_support/android/metrics/android_metrics_service_client.h"
 #include "components/embedder_support/origin_trials/origin_trial_prefs.h"
@@ -226,8 +224,7 @@
   // platforms, pass false for |extend_variations_safe_mode| to opt out of the
   // Extended Variations Safe Mode experiment. See crbug/1220131 for more info.
   variations_field_trial_creator_->SetupFieldTrials(
-      cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
-      switches::kDisableFeatures, variation_ids,
+      variation_ids,
       GetSwitchDependentFeatureOverrides(
           *base::CommandLine::ForCurrentProcess()),
       /*low_entropy_provider=*/nullptr, std::move(feature_list),
diff --git a/ash/drag_drop/drag_drop_controller.cc b/ash/drag_drop/drag_drop_controller.cc
index 5264b93..62e3c88 100644
--- a/ash/drag_drop/drag_drop_controller.cc
+++ b/ash/drag_drop/drag_drop_controller.cc
@@ -87,15 +87,17 @@
   }
 }
 
-bool IsDragDropAllowed(const ui::OSExchangeData* drag_data,
-                       aura::client::DragUpdateInfo& drag_info,
-                       bool is_drop) {
+void DropIfAllowed(const ui::OSExchangeData* drag_data,
+                   aura::client::DragUpdateInfo& drag_info,
+                   base::OnceClosure drop_cb) {
   DCHECK(drag_data);
 
-  return ui::DataTransferPolicyController::HasInstance()
-             ? ui::DataTransferPolicyController::Get()->IsDragDropAllowed(
-                   drag_data->GetSource(), &drag_info.data_endpoint, is_drop)
-             : true;
+  if (ui::DataTransferPolicyController::HasInstance()) {
+    ui::DataTransferPolicyController::Get()->DropIfAllowed(
+        drag_data->GetSource(), &drag_info.data_endpoint, std::move(drop_cb));
+  } else {
+    std::move(drop_cb).Run();
+  }
 }
 
 }  // namespace
@@ -174,6 +176,8 @@
   if (!enabled_ || IsDragDropInProgress())
     return DragOperation::kNone;
 
+  drop_weak_factory_.InvalidateWeakPtrs();
+
   const ui::OSExchangeDataProvider* provider = &data->provider();
   // We do not support touch drag/drop without a drag image, unless it is a tab
   // drag/drop.
@@ -236,8 +240,8 @@
 
   if (TabDragDropDelegate::IsChromeTabDrag(*drag_data_)) {
     DCHECK(!tab_drag_drop_delegate_);
-    tab_drag_drop_delegate_.emplace(root_window, drag_source_window_,
-                                    start_location_);
+    tab_drag_drop_delegate_ = std::make_unique<TabDragDropDelegate>(
+        root_window, drag_source_window_, start_location_);
     static_cast<DragImageView*>(drag_image_widget_->GetContentsView())
         ->SetTouchDragOperationHintOff();
   }
@@ -491,19 +495,14 @@
         aura::client::GetDragDropDelegate(drag_window_);
     if (delegate) {
       drag_info = delegate->OnDragUpdated(e);
-      bool is_drop_allowed = IsDragDropAllowed(drag_data_.get(), drag_info,
-                                               /*is_drop=*/false);
       gfx::NativeCursor cursor = ui::mojom::CursorType::kNoDrop;
-      if (is_drop_allowed) {
-        if (drag_info.drag_operation & ui::DragDropTypes::DRAG_COPY)
-          cursor = ui::mojom::CursorType::kCopy;
-        else if (drag_info.drag_operation & ui::DragDropTypes::DRAG_LINK)
-          cursor = ui::mojom::CursorType::kAlias;
-        else if (drag_info.drag_operation & ui::DragDropTypes::DRAG_MOVE)
-          cursor = ui::mojom::CursorType::kGrabbing;
-      } else {
-        drag_info.drag_operation = ui::DragDropTypes::DRAG_NONE;
-      }
+      if (drag_info.drag_operation & ui::DragDropTypes::DRAG_COPY)
+        cursor = ui::mojom::CursorType::kCopy;
+      else if (drag_info.drag_operation & ui::DragDropTypes::DRAG_LINK)
+        cursor = ui::mojom::CursorType::kAlias;
+      else if (drag_info.drag_operation & ui::DragDropTypes::DRAG_MOVE)
+        cursor = ui::mojom::CursorType::kGrabbing;
+
       Shell::Get()->cursor_manager()->SetCursor(cursor);
     }
   }
@@ -548,48 +547,50 @@
     DragUpdate(target, event);
   DCHECK(target == drag_window_);
 
-  if (!IsDragDropAllowed(drag_data_.get(), current_drag_info_,
-                         /*is_drop=*/true)) {
-    DragCancel();
-    return;
-  }
-
   Shell::Get()->cursor_manager()->SetCursor(ui::mojom::CursorType::kPointer);
 
   aura::client::DragDropDelegate* delegate =
       aura::client::GetDragDropDelegate(target);
-  if (delegate) {
-    ui::DropTargetEvent e(*drag_data_.get(), event.location_f(),
-                          event.root_location_f(), allowed_operations_);
-    e.set_flags(event.flags());
-    ui::Event::DispatcherApi(&e).set_target(target);
 
-    ui::OSExchangeData copied_data(drag_data_->provider().Clone());
-    operation_ = delegate->OnPerformDrop(e, std::move(drag_data_));
-    if (operation_ == DragOperation::kNone && tab_drag_drop_delegate_) {
-      gfx::Point location_in_screen = event.root_location();
-      ::wm::ConvertPointToScreen(target->GetRootWindow(), &location_in_screen);
-      tab_drag_drop_delegate_->Drop(location_in_screen, copied_data);
-      // Override the drag event's drop effect as a move to inform the front-end
-      // that the tab or group was moved. Otherwise, the WebUI tab strip does
-      // not know that a drop resulted in a tab being moved and will temporarily
-      // visually return the tab to its original position. (crbug.com/1081905)
-      operation_ = DragOperation::kMove;
-      drag_image_widget_.reset();
-    } else if (operation_ == DragOperation::kNone) {
-      StartCanceledAnimation(kCancelAnimationDuration);
-    } else {
-      drag_image_widget_.reset();
-    }
-  } else {
-    drag_image_widget_.reset();
-  }
+  aura::client::DragDropDelegate::DropCallback delegate_drop_cb =
+      base::DoNothing();
 
-  if (toplevel_window_drag_delegate_)
-    operation_ = toplevel_window_drag_delegate_->OnToplevelWindowDragDropped();
+  ui::DropTargetEvent e(*drag_data_.get(), event.location_f(),
+                        event.root_location_f(), allowed_operations_);
+  e.set_flags(event.flags());
+  ui::Event::DispatcherApi(&e).set_target(target);
+
+  if (delegate)
+    delegate_drop_cb = delegate->GetDropCallback(e);
+
+  base::ScopedClosureRunner drag_cancel(base::BindOnce(
+      &DragDropController::DragCancel, weak_factory_.GetWeakPtr()));
+
+  gfx::Point drop_location_in_screen = event.root_location();
+  ::wm::ConvertPointToScreen(target->GetRootWindow(), &drop_location_in_screen);
+
+  const bool is_tab_drag_drop = (tab_drag_drop_delegate_.get() != nullptr);
+
+  DropIfAllowed(
+      drag_data_.get(), current_drag_info_,
+      base::BindOnce(&DragDropController::PerformDrop,
+                     drop_weak_factory_.GetWeakPtr(), drop_location_in_screen,
+                     e, std::move(drag_data_), std::move(delegate_drop_cb),
+                     std::move(tab_drag_drop_delegate_),
+                     std::move(drag_cancel)));
 
   Cleanup();
-  if (should_block_during_drag_drop_)
+
+  // Tab drag-n-drop should never be async.
+  if (is_tab_drag_drop)
+    DCHECK(!drag_image_widget_);
+
+  // If the drop is async and cancelled animation isn't running, reset
+  // |drag_image_widget_|.
+  if (!cancel_animation_)
+    drag_image_widget_.reset();
+
+  if (should_block_during_drag_drop_ && quit_closure_)
     std::move(quit_closure_).Run();
 }
 
@@ -633,8 +634,10 @@
     toplevel_window_drag_delegate_->OnToplevelWindowDragCancelled();
 
   Cleanup();
-  StartCanceledAnimation(drag_cancel_animation_duration);
-  if (should_block_during_drag_drop_)
+  // If the drop is async, then |drag_image_widget_| is already reset.
+  if (drag_image_widget_)
+    StartCanceledAnimation(drag_cancel_animation_duration);
+  if (should_block_during_drag_drop_ && quit_closure_)
     std::move(quit_closure_).Run();
 }
 
@@ -700,4 +703,36 @@
   std::unique_ptr<DragDropTracker> holder = std::move(drag_drop_tracker_);
 }
 
+void DragDropController::PerformDrop(
+    const gfx::Point drop_location_in_screen,
+    ui::DropTargetEvent event,
+    std::unique_ptr<ui::OSExchangeData> drag_data,
+    aura::client::DragDropDelegate::DropCallback drop_cb,
+    std::unique_ptr<TabDragDropDelegate> tab_drag_drop_delegate,
+    base::ScopedClosureRunner drag_cancel) {
+  ui::OSExchangeData copied_data(drag_data->provider().Clone());
+  if (drop_cb)
+    std::move(drop_cb).Run(event, std::move(drag_data), operation_);
+
+  if (operation_ == DragOperation::kNone && tab_drag_drop_delegate) {
+    DCHECK(drag_image_widget_);
+    tab_drag_drop_delegate->Drop(drop_location_in_screen, copied_data);
+    // Override the drag event's drop effect as a move to inform the front-end
+    // that the tab or group was moved. Otherwise, the WebUI tab strip does
+    // not know that a drop resulted in a tab being moved and will temporarily
+    // visually return the tab to its original position. (crbug.com/1081905)
+    operation_ = DragOperation::kMove;
+    drag_image_widget_.reset();
+  } else if (operation_ == DragOperation::kNone) {
+    StartCanceledAnimation(kCancelAnimationDuration);
+  } else {
+    drag_image_widget_.reset();
+  }
+
+  if (toplevel_window_drag_delegate_) {
+    operation_ = toplevel_window_drag_delegate_->OnToplevelWindowDragDropped();
+  }
+  drag_cancel.ReplaceClosure(base::DoNothing());
+}
+
 }  // namespace ash
diff --git a/ash/drag_drop/drag_drop_controller.h b/ash/drag_drop/drag_drop_controller.h
index 13bd68f..217817ac 100644
--- a/ash/drag_drop/drag_drop_controller.h
+++ b/ash/drag_drop/drag_drop_controller.h
@@ -125,6 +125,16 @@
   // Helper method to reset everything.
   void Cleanup();
 
+  // Helper method to perform the drop if allowed by
+  // DataTransferPolicyController. If it's run, `drag_cancel` will be replaced.
+  // Otherwise `drag_cancel` will run to cancel the drag.
+  void PerformDrop(const gfx::Point drop_location_in_screen,
+                   ui::DropTargetEvent event,
+                   std::unique_ptr<ui::OSExchangeData> drag_data,
+                   aura::client::DragDropDelegate::DropCallback drop_cb,
+                   std::unique_ptr<TabDragDropDelegate> tab_drag_drop_delegate,
+                   base::ScopedClosureRunner drag_cancel);
+
   bool enabled_ = false;
   views::UniqueWidgetPtr drag_image_widget_;
   gfx::Vector2d drag_image_offset_;
@@ -134,7 +144,7 @@
   aura::client::DragUpdateInfo current_drag_info_;
 
   // Used when processing a Chrome tab drag from a WebUI tab strip.
-  absl::optional<TabDragDropDelegate> tab_drag_drop_delegate_;
+  std::unique_ptr<TabDragDropDelegate> tab_drag_drop_delegate_;
 
   // Window that is currently under the drag cursor.
   aura::Window* drag_window_ = nullptr;
@@ -174,6 +184,9 @@
 
   ToplevelWindowDragDelegate* toplevel_window_drag_delegate_ = nullptr;
 
+  // Weak ptr for async drop callbacks to be invalidated if a new drag starts.
+  base::WeakPtrFactory<DragDropController> drop_weak_factory_{this};
+
   base::WeakPtrFactory<DragDropController> weak_factory_{this};
 };
 
diff --git a/ash/drag_drop/drag_drop_controller_unittest.cc b/ash/drag_drop/drag_drop_controller_unittest.cc
index 681db37..13a19965 100644
--- a/ash/drag_drop/drag_drop_controller_unittest.cc
+++ b/ash/drag_drop/drag_drop_controller_unittest.cc
@@ -132,12 +132,24 @@
   void OnDragExited() override { num_drag_exits_++; }
 
   DragOperation OnPerformDrop(const ui::DropTargetEvent& event) override {
-    num_drops_++;
-    return DragOperation::kCopy;
+    DragOperation output_drag_op = DragOperation::kNone;
+    PerformDrop(event, output_drag_op);
+    return output_drag_op;
+  }
+
+  DropCallback GetDropCallback(const ui::DropTargetEvent& event) override {
+    return base::BindOnce(&DragTestView::PerformDrop, base::Unretained(this));
   }
 
   void OnDragDone() override { drag_done_received_ = true; }
 
+ private:
+  void PerformDrop(const ui::DropTargetEvent& event,
+                   ui::mojom::DragOperation& output_drag_op) {
+    num_drops_++;
+    output_drag_op = DragOperation::kCopy;
+  }
+
   DISALLOW_COPY_AND_ASSIGN(DragTestView);
 };
 
@@ -289,18 +301,28 @@
   DragOperation OnPerformDrop(
       const ui::DropTargetEvent& event,
       std::unique_ptr<ui::OSExchangeData> data) override {
-    EXPECT_EQ(State::kDragUpdateInvoked, state_);
-    EXPECT_EQ(window_, event.target());
-    state_ = State::kPerformDropInvoked;
-    return DragOperation::kMove;
+    DragOperation output_drag_op = DragOperation::kNone;
+    PerformDrop(event, std::move(data), output_drag_op);
+
+    return output_drag_op;
   }
 
   DropCallback GetDropCallback(const ui::DropTargetEvent& event) override {
-    NOTIMPLEMENTED();
-    return base::NullCallback();
+    return base::BindOnce(&EventTargetTestDelegate::PerformDrop,
+                          base::Unretained(this));
   }
 
  private:
+  void PerformDrop(const ui::DropTargetEvent& event,
+                   std::unique_ptr<ui::OSExchangeData> data,
+                   ui::mojom::DragOperation& output_drag_op) {
+    EXPECT_EQ(State::kDragUpdateInvoked, state_);
+    EXPECT_EQ(window_, event.target());
+
+    state_ = State::kPerformDropInvoked;
+    output_drag_op = DragOperation::kMove;
+  }
+
   aura::Window* const window_;
   State state_{State::kNotInvoked};
 
@@ -468,6 +490,10 @@
 
   MockShellDelegate* mock_shell_delegate() { return mock_shell_delegate_; }
 
+  gfx::LinearAnimation* cancel_animation() {
+    return drag_drop_controller_->cancel_animation_.get();
+  }
+
   void CompleteCancelAnimation() {
     CompletableLinearAnimation* animation =
         static_cast<CompletableLinearAnimation*>(
@@ -1579,15 +1605,15 @@
                     const ui::DataTransferEndpoint* const data_dst,
                     const absl::optional<size_t> size));
   MOCK_METHOD5(PasteIfAllowed,
-               void((const ui::DataTransferEndpoint* const data_src,
-                     const ui::DataTransferEndpoint* const data_dst,
-                     const absl::optional<size_t> size,
-                     content::RenderFrameHost* rfh,
-                     base::OnceCallback<void(bool)> callback)));
-  MOCK_METHOD3(IsDragDropAllowed,
-               bool(const ui::DataTransferEndpoint* const data_src,
+               void(const ui::DataTransferEndpoint* const data_src,
                     const ui::DataTransferEndpoint* const data_dst,
-                    const bool is_drop));
+                    const absl::optional<size_t> size,
+                    content::RenderFrameHost* rfh,
+                    base::OnceCallback<void(bool)> callback));
+  MOCK_METHOD3(DropIfAllowed,
+               void(const ui::DataTransferEndpoint* data_src,
+                    const ui::DataTransferEndpoint* data_dst,
+                    base::OnceClosure drop_cb));
 };
 
 }  // namespace
@@ -1608,12 +1634,11 @@
   auto data(std::make_unique<ui::OSExchangeData>());
   data->SetString(u"I am being dragged");
 
-  // Drag update.
-  EXPECT_CALL(dlp_contoller, IsDragDropAllowed(_, _, /*is_drop=*/false))
-      .WillOnce(::testing::Return(true));
   // Drop.
-  EXPECT_CALL(dlp_contoller, IsDragDropAllowed(_, _, /*is_drop=*/true))
-      .WillOnce(::testing::Return(true));
+  EXPECT_CALL(dlp_contoller, DropIfAllowed(_, _, _))
+      .WillOnce([&](const ui::DataTransferEndpoint* data_src,
+                    const ui::DataTransferEndpoint* data_dst,
+                    base::OnceClosure drop_cb) { std::move(drop_cb).Run(); });
 
   drag_drop_controller_->StartDragAndDrop(
       std::move(data), window->GetRootWindow(), window.get(), gfx::Point(5, 5),
@@ -1646,12 +1671,7 @@
   auto data(std::make_unique<ui::OSExchangeData>());
   data->SetString(u"I am being dragged");
 
-  // Drag update.
-  EXPECT_CALL(dlp_contoller, IsDragDropAllowed(_, _, /*is_drop=*/false))
-      .WillOnce(::testing::Return(false));
-  // Drop.
-  EXPECT_CALL(dlp_contoller, IsDragDropAllowed(_, _, /*is_drop=*/true))
-      .WillOnce(::testing::Return(false));
+  EXPECT_CALL(dlp_contoller, DropIfAllowed(_, _, _));
 
   drag_drop_controller_->StartDragAndDrop(
       std::move(data), window->GetRootWindow(), window.get(), gfx::Point(5, 5),
@@ -1664,7 +1684,61 @@
   // For perform drop
   generator.ReleaseLeftButton();
 
+  EXPECT_TRUE(cancel_animation());
+  EXPECT_TRUE(GetDragImageWindow());
   EXPECT_EQ(EventTargetTestDelegate::State::kDragExitInvoked, delegate.state());
 }
 
+TEST_F(DragDropControllerTest, DlpAsyncDrop) {
+  std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
+      aura::test::TestWindowDelegate::CreateSelfDestroyingDelegate(), -1,
+      gfx::Rect(0, 0, 100, 100)));
+  EventTargetTestDelegate delegate(window.get());
+  aura::client::SetDragDropDelegate(window.get(), &delegate);
+
+  MockDataTransferPolicyController dlp_contoller;
+
+  // Posted task will be run when the inner loop runs in StartDragAndDrop.
+  ui::test::EventGenerator generator(window->GetRootWindow(), window.get());
+  generator.PressLeftButton();
+
+  auto data(std::make_unique<ui::OSExchangeData>());
+  data->SetString(u"I am being dragged");
+
+  base::OnceClosure drop_callback;
+
+  // Hold Drop.
+  EXPECT_CALL(dlp_contoller, DropIfAllowed(_, _, _))
+      .WillOnce([&](const ui::DataTransferEndpoint* data_src,
+                    const ui::DataTransferEndpoint* data_dst,
+                    base::OnceClosure drop_cb) {
+        drop_callback = std::move(drop_cb);
+      });
+
+  drag_drop_controller_->StartDragAndDrop(
+      std::move(data), window->GetRootWindow(), window.get(), gfx::Point(5, 5),
+      ui::DragDropTypes::DRAG_MOVE, ui::mojom::DragEventSource::kMouse);
+
+  // For drag enter
+  generator.MoveMouseBy(0, 1);
+  // For drag update
+  generator.MoveMouseBy(0, 1);
+  // For perform drop
+  generator.ReleaseLeftButton();
+
+  EXPECT_FALSE(cancel_animation());
+  EXPECT_FALSE(GetDragImageWindow());
+
+  data = std::make_unique<ui::OSExchangeData>();
+  data->SetString(u"I am being dragged 2");
+  drag_drop_controller_->StartDragAndDrop(
+      std::move(data), window->GetRootWindow(), window.get(), gfx::Point(5, 5),
+      ui::DragDropTypes::DRAG_MOVE, ui::mojom::DragEventSource::kMouse);
+
+  std::move(drop_callback).Run();
+
+  EXPECT_EQ(EventTargetTestDelegate::State::kDragUpdateInvoked,
+            delegate.state());
+}
+
 }  // namespace ash
diff --git a/ash/drag_drop/drag_drop_unittest.cc b/ash/drag_drop/drag_drop_unittest.cc
index 8b670ed..043feea 100644
--- a/ash/drag_drop/drag_drop_unittest.cc
+++ b/ash/drag_drop/drag_drop_unittest.cc
@@ -65,13 +65,24 @@
   }
   ui::mojom::DragOperation OnPerformDrop(
       const ui::DropTargetEvent& event) override {
-    dropped_ = true;
-    return ui::mojom::DragOperation::kMove;
+    ui::mojom::DragOperation output_drag_op = ui::mojom::DragOperation::kNone;
+    PerformDrop(event, output_drag_op);
+    return output_drag_op;
+  }
+
+  DropCallback GetDropCallback(const ui::DropTargetEvent& event) override {
+    return base::BindOnce(&TargetView::PerformDrop, base::Unretained(this));
   }
 
   bool dropped() const { return dropped_; }
 
  private:
+  void PerformDrop(const ui::DropTargetEvent& event,
+                   ui::mojom::DragOperation& output_drag_op) {
+    dropped_ = true;
+    output_drag_op = ui::mojom::DragOperation::kMove;
+  }
+
   bool dropped_;
 };
 
diff --git a/ash/system/bluetooth/bluetooth_detailed_view_legacy.cc b/ash/system/bluetooth/bluetooth_detailed_view_legacy.cc
index 4e04fac..56fa06c 100644
--- a/ash/system/bluetooth/bluetooth_detailed_view_legacy.cc
+++ b/ash/system/bluetooth/bluetooth_detailed_view_legacy.cc
@@ -227,7 +227,7 @@
     index = AddSameTypeDevicesToScrollList(paired_not_connected_devices,
                                            old_device_map, index, false, false);
   } else if (paired_devices_heading_) {
-    scroll_content()->RemoveChildView(paired_devices_heading_);
+    scroll_content()->RemoveChildViewT(paired_devices_heading_);
     paired_devices_heading_ = nullptr;
   }
 
@@ -245,7 +245,7 @@
 
   if (unpaired_devices_heading_ &&
       (discovered_not_paired_devices.empty() || !has_paired_devices)) {
-    scroll_content()->RemoveChildView(unpaired_devices_heading_);
+    scroll_content()->RemoveChildViewT(unpaired_devices_heading_);
     unpaired_devices_heading_ = nullptr;
   }
 
@@ -259,14 +259,14 @@
       scroll_content()->ReorderChildView(bluetooth_discovering_label_, index++);
     }
   } else if (bluetooth_discovering_label_) {
-    scroll_content()->RemoveChildView(bluetooth_discovering_label_);
+    scroll_content()->RemoveChildViewT(bluetooth_discovering_label_);
     bluetooth_discovering_label_ = nullptr;
   }
 
   // Remove views for devices from old_device_map that are not in device_map_.
   for (auto& view_and_address : old_device_map) {
     if (device_map_.find(view_and_address.first) == device_map_.end()) {
-      scroll_content()->RemoveChildView(view_and_address.first);
+      scroll_content()->RemoveChildViewT(view_and_address.first);
     }
   }
 
diff --git a/ash/webui/diagnostics_ui/backend/networking_log.cc b/ash/webui/diagnostics_ui/backend/networking_log.cc
index 3169d0ec..48a82ab 100644
--- a/ash/webui/diagnostics_ui/backend/networking_log.cc
+++ b/ash/webui/diagnostics_ui/backend/networking_log.cc
@@ -53,6 +53,8 @@
 const char kNetworkAddedEventTemplate[] =
     "%s network [%s] started in state %s\n";
 const char kNetworkRemovedEventTemplate[] = "%s network [%s] removed\n";
+const char kNetworkStateChangedEventTemplate[] =
+    "%s network [%s] changed state from %s to %s\n";
 
 std::string GetSubnetMask(int prefix) {
   uint32_t mask = (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF;
@@ -240,8 +242,11 @@
 void NetworkingLog::UpdateNetworkState(mojom::NetworkPtr network) {
   if (!base::Contains(latest_network_states_, network->observer_guid)) {
     LogNetworkAdded(network);
+    latest_network_states_.emplace(network->observer_guid, std::move(network));
+    return;
   }
 
+  LogNetworkChanges(network);
   latest_network_states_[network->observer_guid] = std::move(network);
 }
 
@@ -266,5 +271,25 @@
   LogEvent(line);
 }
 
+void NetworkingLog::LogNetworkChanges(const mojom::NetworkPtr& new_state) {
+  DCHECK(base::Contains(latest_network_states_, new_state->observer_guid));
+  const mojom::NetworkPtr& old_state =
+      latest_network_states_.at(new_state->observer_guid);
+  if (old_state->state != new_state->state) {
+    LogNetworkStateChanged(old_state, new_state);
+  }
+}
+
+void NetworkingLog::LogNetworkStateChanged(const mojom::NetworkPtr& old_state,
+                                           const mojom::NetworkPtr& new_state) {
+  const std::string line =
+      base::StringPrintf(kNetworkStateChangedEventTemplate,
+                         GetNetworkType(new_state->type).c_str(),
+                         new_state->mac_address.value_or("").c_str(),
+                         GetNetworkStateString(old_state->state).c_str(),
+                         GetNetworkStateString(new_state->state).c_str());
+  LogEvent(line);
+}
+
 }  // namespace diagnostics
 }  // namespace ash
diff --git a/ash/webui/diagnostics_ui/backend/networking_log.h b/ash/webui/diagnostics_ui/backend/networking_log.h
index af0e92de..fd21fb7 100644
--- a/ash/webui/diagnostics_ui/backend/networking_log.h
+++ b/ash/webui/diagnostics_ui/backend/networking_log.h
@@ -38,9 +38,25 @@
   void UpdateNetworkState(mojom::NetworkPtr network);
 
  private:
+  // Writes the `event_string` to the `event_log_`.
   void LogEvent(const std::string& event_string);
+
+  // Logs an event whenever a new network is seen in the network list
+  // sent to UpdateNetworkList().
   void LogNetworkAdded(const mojom::NetworkPtr& network);
+
+  // Logs an event whenever a network is removed from the network list
+  // sent to UpdateNetworkList().
   void LogNetworkRemoved(const mojom::NetworkPtr& network);
+
+  // Top level function that determines which state changes should be
+  // logged and calls the appropriate specialized method below.
+  void LogNetworkChanges(const mojom::NetworkPtr& network);
+
+  // Logs when the state of the network changes.
+  void LogNetworkStateChanged(const mojom::NetworkPtr& old_state,
+                              const mojom::NetworkPtr& new_state);
+
   AsyncLog event_log_;
   std::string active_guid_;
   base::flat_map<std::string, mojom::NetworkPtr> latest_network_states_;
diff --git a/ash/webui/diagnostics_ui/backend/networking_log_unittest.cc b/ash/webui/diagnostics_ui/backend/networking_log_unittest.cc
index e085318..d446757 100644
--- a/ash/webui/diagnostics_ui/backend/networking_log_unittest.cc
+++ b/ash/webui/diagnostics_ui/backend/networking_log_unittest.cc
@@ -229,7 +229,7 @@
   ExpectCorrectLogLine(expected_line, events_lines[1]);
 }
 
-TEST_F(NetworkingLogTest, RemoveNetworkEvent) {
+TEST_F(NetworkingLogTest, NetworkEvents) {
   const std::string expected_guid = "guid";
   const std::string expected_name = "name";
   const std::string expected_mac_address = "84:C5:A6:30:3F:31";
@@ -240,24 +240,42 @@
 
   NetworkingLog log(temp_dir_.GetPath());
 
-  // Add then remove ethernet network.
+  // Add the network.
   log.UpdateNetworkList({expected_guid}, expected_guid);
   log.UpdateNetworkState(test_info.Clone());
+
+  // Change the state of the network from Online to Disabled.
+  mojom::NetworkPtr new_state = test_info.Clone();
+  new_state->state = mojom::NetworkState::kDisabled;
+  log.UpdateNetworkState(std::move(new_state));
+  task_environment_.RunUntilIdle();
+
+  // Remove the network.
   log.UpdateNetworkList({}, "expected_guid");
   task_environment_.RunUntilIdle();
 
-  // Expect one title and one event for adding the network and one
-  // for removing.
+  // Split the log for verification.
   const std::string events_log = log.GetNetworkEvents();
   const std::vector<std::string> events_lines = GetLogLines(events_log);
-  EXPECT_EQ(3u, events_lines.size());
-  EXPECT_EQ("--- Network Events ---", events_lines[0]);
+  EXPECT_EQ(4u, events_lines.size());
 
+  // Verify section header.
+  size_t upto_line = 0;
+  EXPECT_EQ("--- Network Events ---", events_lines[upto_line++]);
+
+  // Verify add event.
   std::string expected_line =
       "Ethernet network [" + expected_mac_address + "] started in state Online";
-  ExpectCorrectLogLine(expected_line, events_lines[1]);
+  ExpectCorrectLogLine(expected_line, events_lines[upto_line++]);
+
+  // Verify state change event.
+  expected_line = "Ethernet network [" + expected_mac_address +
+                  "] changed state from Online to Disabled";
+  ExpectCorrectLogLine(expected_line, events_lines[upto_line++]);
+
+  // Verify remove event.
   expected_line = "Ethernet network [" + expected_mac_address + "] removed";
-  ExpectCorrectLogLine(expected_line, events_lines[2]);
+  ExpectCorrectLogLine(expected_line, events_lines[upto_line++]);
 }
 
 }  // namespace diagnostics
diff --git a/ash/webui/diagnostics_ui/diagnostics_ui.cc b/ash/webui/diagnostics_ui/diagnostics_ui.cc
index 72fc4a0..bba5438 100644
--- a/ash/webui/diagnostics_ui/diagnostics_ui.cc
+++ b/ash/webui/diagnostics_ui/diagnostics_ui.cc
@@ -57,9 +57,13 @@
 
 void AddDiagnosticsStrings(content::WebUIDataSource* html_source) {
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
+      {"arcDnsResolutionFailedText",
+       IDS_DIAGNOSTICS_ARC_DNS_RESOLUTION_FAILED_TEXT},
       {"arcDnsResolutionRoutineText",
        IDS_NETWORK_DIAGNOSTICS_ARC_DNS_RESOLUTION},
+      {"arcHttpFailedText", IDS_DIAGNOSTICS_ARC_HTTP_FAILED_TEXT},
       {"arcHttpRoutineText", IDS_NETWORK_DIAGNOSTICS_ARC_HTTP},
+      {"arcPingFailedText", IDS_DIAGNOSTICS_ARC_PING_FAILED_TEXT},
       {"arcPingRoutineText", IDS_NETWORK_DIAGNOSTICS_ARC_PING},
       {"batteryCalculatingText", IDS_DIAGNOSTICS_BATTERY_CALCULATING_TEXT},
       {"batteryChargeRoutineText", IDS_DIAGNOSTICS_BATTERY_CHARGE_ROUTINE_TEXT},
@@ -75,6 +79,7 @@
       {"batteryHealthTooltipText", IDS_DIAGNOSTICS_BATTERY_HEALTH_TOOLTIP_TEXT},
       {"batteryTitle", IDS_DIAGNOSTICS_BATTERY_TITLE},
       {"boardAndVersionInfo", IDS_DIAGNOSTICS_DEVICE_INFO_TEXT},
+      {"captivePortalFailedText", IDS_DIAGNOSTICS_CAPTIVE_PORTAL_FAILED_TEXT},
       {"captivePortalRoutineText", IDS_NETWORK_DIAGNOSTICS_CAPTIVE_PORTAL},
       {"cellularLabel", IDS_NETWORK_TYPE_CELLULAR},
       {"chargeTestResultText", IDS_CHARGE_TEST_RESULT},
@@ -106,20 +111,31 @@
       {"disabledText", IDS_DIAGNOSTICS_DISABLED_TEXT},
       {"dischargeTestResultText", IDS_DISCHARGE_TEST_RESULT},
       {"dnsGroupText", IDS_NETWORK_DIAGNOSTICS_DNS_GROUP},
+      {"dnsLatencyFailedText", IDS_DIAGNOSTICS_DNS_LATENCY_FAILED_TEXT},
       {"dnsLatencyRoutineText", IDS_NETWORK_DIAGNOSTICS_DNS_LATENCY},
+      {"dnsResolutionFailedText", IDS_DIAGNOSTICS_DNS_RESOLUTION_FAILED_TEXT},
       {"dnsResolutionRoutineText", IDS_NETWORK_DIAGNOSTICS_DNS_RESOLUTION},
+      {"dnsResolverPresentFailedText",
+       IDS_DIAGNOSTICS_DNS_RESOLVER_PRESENT_FAILED_TEXT},
       {"dnsResolverPresentRoutineText",
        IDS_NETWORK_DIAGNOSTICS_DNS_RESOLVER_PRESENT},
       {"ethernetLabel", IDS_NETWORK_TYPE_ETHERNET},
       {"firewallGroupText", IDS_NETWORK_DIAGNOSTICS_FIREWALL_GROUP},
+      {"gatewayCanBePingedFailedText",
+       IDS_DIAGNOSTICS_GATEWAY_CAN_BE_PINGED_FAILED_TEXT},
       {"gatewayCanBePingedRoutineText",
        IDS_NETWORK_DIAGNOSTICS_GATEWAY_CAN_BE_PINGED},
       {"gatewayRoutineText", IDS_NETWORK_DIAGNOSTICS_GATEWAY_GROUP},
+      {"hasSecureWifiConnectionFailedText",
+       IDS_DIAGNOSTICS_HAS_SECURE_WIFI_CONNECTION_FAILED_TEXT},
       {"hasSecureWiFiConnectionRoutineText",
        IDS_NETWORK_DIAGNOSTICS_HAS_SECURE_WIFI_CONNECTION},
       {"hideReportText", IDS_DIAGNOSTICS_HIDE_REPORT_TEXT},
+      {"httpFirewallFailedText", IDS_DIAGNOSTICS_HTTP_FIREWALL_FAILED_TEXT},
       {"httpFirewallRoutineText", IDS_NETWORK_DIAGNOSTICS_HTTP_FIREWALL},
+      {"httpsFirewallFailedText", IDS_DIAGNOSTICS_HTTPS_FIREWALL_FAILED_TEXT},
       {"httpsFirewallRoutineText", IDS_NETWORK_DIAGNOSTICS_HTTPS_FIREWALL},
+      {"httpsLatencyFailedText", IDS_DIAGNOSTICS_HTTPS_LATENCY_FAILED_TEXT},
       {"httpsLatencyRoutineText", IDS_NETWORK_DIAGNOSTICS_HTTPS_LATENCY},
       {"inputCategoryKeyboard", IDS_INPUT_DIAGNOSTICS_CATEGORY_KEYBOARD},
       {"inputCategoryTouchpad", IDS_INPUT_DIAGNOSTICS_CATEGORY_TOUCHPAD},
@@ -148,6 +164,8 @@
        IDS_NETWORK_DIAGNOSTICS_IP_CONFIG_INFO_DRAWER_SUBNET_MASK},
       {"ipConfigInfoDrawerTitle",
        IDS_NETWORK_DIAGNOSTICS_IP_CONFIG_INFO_DRAWER_TITLE},
+      {"lanConnectivityFailedText",
+       IDS_DIAGNOSTICS_LAN_CONNECTIVITY_FAILED_TEXT},
       {"lanConnectivityGroupText", IDS_NETWORK_DIAGNOSTICS_CONNECTION_GROUP},
       {"lanConnectivityRoutineText", IDS_NETWORK_DIAGNOSTICS_LAN_CONNECTIVITY},
       {"learnMore", IDS_DIANOSTICS_LEARN_MORE_LABEL},
@@ -211,7 +229,6 @@
       {"reconnectLinkText", IDS_DIAGNOSTICS_RECONNECT_LINK_TEXT},
       {"remainingCharge", IDS_DIAGNOSTICS_REMAINING_CHARGE_LABEL},
       {"routineEntryText", IDS_DIANOSTICS_ROUTINE_ENTRY_TEXT},
-      {"routineFailedText", IDS_DIAGNOSTICS_FAILED_TEST_TEXT},
       {"routineNameText", IDS_DIANOSTICS_ROUTINE_NAME_TEXT},
       {"runAgainButtonText", IDS_DIAGNOSTICS_RUN_AGAIN_BUTTON_TEXT},
       {"routineRemainingMin", IDS_DIAGNOSTICS_ROUTINE_REMAINING_MIN},
@@ -230,6 +247,7 @@
        IDS_DIAGNOSTICS_SESSION_LOG_TOAST_TEXT_FAILURE},
       {"sessionLogToastTextSuccess",
        IDS_DIAGNOSTICS_SESSION_LOG_TOAST_TEXT_SUCCESS},
+      {"signalStrengthFailedText", IDS_DIAGNOSTICS_SIGNAL_STRENGTH_FAILED_TEXT},
       {"signalStrengthRoutineText", IDS_NETWORK_DIAGNOSTICS_SIGNAL_STRENGTH},
       {"stopTestButtonText", IDS_DIAGNOSTICS_STOP_TEST_BUTTON_TEXT},
       {"systemText", IDS_DIAGNOSTICS_SYSTEM},
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_utils.js b/ash/webui/diagnostics_ui/resources/diagnostics_utils.js
index c93b183..69d3423 100644
--- a/ash/webui/diagnostics_ui/resources/diagnostics_utils.js
+++ b/ash/webui/diagnostics_ui/resources/diagnostics_utils.js
@@ -214,3 +214,55 @@
 export function formatMacAddress(macAddress) {
   return `${loadTimeData.getString('macAddressLabel')}: ${macAddress}`;
 }
+
+/**
+ * Resolves a networking routine type to its corresponding localized failure
+ * message.
+ * @param {!RoutineType} routineType
+ * @return {string}
+ */
+export function getRoutineFailureMessage(routineType) {
+  switch (routineType) {
+    case RoutineType.kCaptivePortal:
+      return loadTimeData.getString('captivePortalFailedText');
+    case RoutineType.kDnsLatency:
+      return loadTimeData.getString('dnsLatencyFailedText');
+    case RoutineType.kDnsResolution:
+      return loadTimeData.getString('dnsResolutionFailedText');
+    case RoutineType.kDnsResolverPresent:
+      return loadTimeData.getString('dnsResolverPresentFailedText');
+    case RoutineType.kGatewayCanBePinged:
+      return loadTimeData.getString('gatewayCanBePingedFailedText');
+    case RoutineType.kHasSecureWiFiConnection:
+      return loadTimeData.getString('hasSecureWiFiConnectionFailedText');
+    case RoutineType.kHttpFirewall:
+      return loadTimeData.getString('httpFirewallFailedText');
+    case RoutineType.kHttpsFirewall:
+      return loadTimeData.getString('httpsFirewallFailedText');
+    case RoutineType.kHttpsLatency:
+      return loadTimeData.getString('httpsLatencyFailedText');
+    case RoutineType.kLanConnectivity:
+      return loadTimeData.getString('lanConnectivityFailedText');
+    case RoutineType.kSignalStrength:
+      return loadTimeData.getString('signalStrengthFailedText');
+    case RoutineType.kArcHttp:
+      return loadTimeData.getString('arcHttpFailedText');
+    case RoutineType.kArcPing:
+      return loadTimeData.getString('arcPingFailedText');
+    case RoutineType.kArcDnsResolution:
+      return loadTimeData.getString('arcDnsResolutionFailedText');
+    case RoutineType.kBatteryCharge:
+    case RoutineType.kBatteryDischarge:
+    case RoutineType.kCpuCache:
+    case RoutineType.kCpuStress:
+    case RoutineType.kCpuFloatingPoint:
+    case RoutineType.kCpuPrime:
+    case RoutineType.kMemory:
+      assertNotReached();
+      return '';
+    default:
+      // Values should always be found in the enum.
+      assertNotReached();
+      return '';
+  }
+}
diff --git a/ash/webui/diagnostics_ui/resources/routine_result_entry.html b/ash/webui/diagnostics_ui/resources/routine_result_entry.html
index fe5526b..c7cb1256 100644
--- a/ash/webui/diagnostics_ui/resources/routine_result_entry.html
+++ b/ash/webui/diagnostics_ui/resources/routine_result_entry.html
@@ -131,7 +131,8 @@
         <iron-icon icon="cr:open-in-new"></iron-icon>
       </a>
     </span>
-    <span class="routineLinkContainer" hidden$="[[!item.failedTest]]">
+    <span id="failedTestText" class="routineLinkContainer"
+        hidden$="[[!item.failedTest]]">
       [[computeFailedTestText_(item.failedTest)]]
     </span>
   </div>
diff --git a/ash/webui/diagnostics_ui/resources/routine_result_entry.js b/ash/webui/diagnostics_ui/resources/routine_result_entry.js
index 8d1b136..f9698db 100644
--- a/ash/webui/diagnostics_ui/resources/routine_result_entry.js
+++ b/ash/webui/diagnostics_ui/resources/routine_result_entry.js
@@ -12,6 +12,7 @@
 import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {RoutineResult, RoutineType, StandardRoutineResult} from './diagnostics_types.js';
+import {getRoutineFailureMessage} from './diagnostics_utils.js';
 import {RoutineGroup} from './routine_group.js';
 import {ExecutionProgress, ResultStatusItem} from './routine_list_executor.js';
 import {BadgeType} from './text_badge.js';
@@ -334,7 +335,6 @@
       return '';
     }
 
-    return loadTimeData.getStringF(
-        'routineFailedText', getRoutineType(this.item.failedTest));
+    return getRoutineFailureMessage(this.item.failedTest);
   },
 });
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
index b9175f8..ee15e553 100644
--- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
+++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -71,6 +71,10 @@
     private static final String REACHED_CODE_SAMPLING_INTERVAL_KEY =
             "reached_code_sampling_interval";
 
+    // Compile time switch for sharing RELRO between the browser and the app zygote.
+    // TODO(crbug.com/1154224): remove when the issue is closed.
+    private static final boolean ALLOW_CHROMIUM_LINKER_IN_ZYGOTE = false;
+
     // Default sampling interval for reached code profiler in microseconds.
     private static final int DEFAULT_REACHED_CODE_SAMPLING_INTERVAL_US = 10000;
 
@@ -155,6 +159,12 @@
         int CHILD_WITHOUT_ZYGOTE = 2;
     }
 
+    // Returns true when sharing RELRO between the browser process and the app zygote should *not*
+    // be attempted.
+    public static boolean mainProcessIntendsToProvideRelroFd() {
+        return !ALLOW_CHROMIUM_LINKER_IN_ZYGOTE || Build.VERSION.SDK_INT <= Build.VERSION_CODES.R;
+    }
+
     /**
      * Inner class encapsulating points of communication between instances of LibraryLoader in
      * different processes.
diff --git a/base/files/file_path_watcher_fuchsia.cc b/base/files/file_path_watcher_fuchsia.cc
index a7c61b1..1085a7e 100644
--- a/base/files/file_path_watcher_fuchsia.cc
+++ b/base/files/file_path_watcher_fuchsia.cc
@@ -5,7 +5,7 @@
 #include "base/files/file_path_watcher.h"
 
 #include "base/files/file_path.h"
-#include "base/memory/ptr_util.h"
+#include "base/notreached.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 
 namespace base {
@@ -19,30 +19,24 @@
   FilePathWatcherImpl& operator=(const FilePathWatcherImpl&) = delete;
   ~FilePathWatcherImpl() override = default;
 
+  // FilePathWatcher::PlatformDelegate:
   bool Watch(const FilePath& path,
              Type type,
              const FilePathWatcher::Callback& callback) override;
-
   void Cancel() override;
-
- private:
-  FilePathWatcher::Callback callback_;
-  FilePath target_;
 };
 
 bool FilePathWatcherImpl::Watch(const FilePath& path,
                                 Type type,
                                 const FilePathWatcher::Callback& callback) {
   DCHECK(!callback.is_null());
-  DCHECK(callback_.is_null());
 
-  callback_ = callback;
-  NOTIMPLEMENTED();
+  NOTIMPLEMENTED_LOG_ONCE();
   return false;
 }
 
 void FilePathWatcherImpl::Cancel() {
-  NOTIMPLEMENTED();
+  set_cancelled();
 }
 
 }  // namespace
diff --git a/base/metrics/field_trial.h b/base/metrics/field_trial.h
index 0555533..e3b860a 100644
--- a/base/metrics/field_trial.h
+++ b/base/metrics/field_trial.h
@@ -232,7 +232,7 @@
   // be done from the UI thread.
   void SetForced();
 
-  // Enable benchmarking sets field trials to a common setting.
+  // Supports benchmarking by causing field trials' default groups to be chosen.
   static void EnableBenchmarking();
 
   // Creates a FieldTrial object with the specified parameters, to be used for
@@ -381,8 +381,8 @@
   // Reference to related field trial struct and data in shared memory.
   FieldTrialRef ref_;
 
-  // When benchmarking is enabled, field trials all revert to the 'default'
-  // group.
+  // Denotes whether benchmarking is enabled. In this case, field trials all
+  // revert to the default group.
   static bool enable_benchmarking_;
 };
 
@@ -424,15 +424,16 @@
   // Destructor Release()'s references to all registered FieldTrial instances.
   ~FieldTrialList();
 
-  // Get a FieldTrial instance from the factory.
+  // Gets a FieldTrial instance from the factory.
   //
-  // |name| is used to register the instance with the FieldTrialList class,
-  // and can be used to find the trial (only one trial can be present for each
-  // name). |default_group_name| is the name of the default group which will
-  // be chosen if none of the subsequent appended groups get to be chosen.
+  // |trial_name| (a) is used to register the instance with the FieldTrialList
+  // class and (b) can be used to find the trial (only one trial can be present
+  // for each name). |default_group_name| is the name of the group that is
+  // chosen if none of the subsequent appended groups are chosen. Note that the
+  // default group is also chosen whenever |enable_benchmarking_| is true.
   // |default_group_number| can receive the group number of the default group as
   // AppendGroup returns the number of the subsequence groups. |trial_name| and
-  // |default_group_name| may not be empty but |default_group_number| can be
+  // |default_group_name| must not be empty, but |default_group_number| can be
   // null if the value is not needed.
   //
   // Group probabilities that are later supplied must sum to less than or equal
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index 5b932ce..59caa7b4 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -420,7 +420,6 @@
     "/DELAYLOAD:ncrypt.dll",
     "/DELAYLOAD:ole32.dll",
     "/DELAYLOAD:oleacc.dll",
-    "/DELAYLOAD:prntvpt.dll",
     "/DELAYLOAD:propsys.dll",
     "/DELAYLOAD:psapi.dll",
     "/DELAYLOAD:rpcrt4.dll",
diff --git a/build/fuchsia/linux.sdk.sha1 b/build/fuchsia/linux.sdk.sha1
index 42aad36..f48d2fd 100644
--- a/build/fuchsia/linux.sdk.sha1
+++ b/build/fuchsia/linux.sdk.sha1
@@ -1 +1 @@
-6.20210923.0.1
+6.20210923.2.1
diff --git a/build/fuchsia/mac.sdk.sha1 b/build/fuchsia/mac.sdk.sha1
index e2f52c9..f48d2fd 100644
--- a/build/fuchsia/mac.sdk.sha1
+++ b/build/fuchsia/mac.sdk.sha1
@@ -1 +1 @@
-6.20210923.1.1
+6.20210923.2.1
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index e63792a..092b64fc 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -2456,6 +2456,7 @@
   sources = [
     "../browser/attribution_reporting/android/java/src/org/chromium/chrome/browser/attribution_reporting/AttributionReportingProvider.java",
     "java/src/com/google/ipc/invalidation/ticl/android2/channel/GcmRegistrationTaskService.java",
+    "java/src/org/chromium/chrome/app/TrichromeZygotePreload.java",
     "java/src/org/chromium/chrome/browser/ChromeBackgroundService.java",
     "java/src/org/chromium/chrome/browser/ChromeBackupAgent.java",
     "java/src/org/chromium/chrome/browser/DeferredStartupHandler.java",
@@ -3694,7 +3695,6 @@
   sources = [
     # Files under a feature's public/ dir are included in chrome_java's source
     # files, so include these files in chrome_jni_headers.
-    "feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceScopeDependencyProvider.java",
     "feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedPersistentKeyValueCache.java",
     "feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedProcessScopeDependencyProvider.java",
     "feed/core/java/src/org/chromium/chrome/browser/feed/v2/FeedStream.java",
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni
index 5407a0c..bb453b6 100644
--- a/chrome/android/chrome_java_resources.gni
+++ b/chrome/android/chrome_java_resources.gni
@@ -15,7 +15,7 @@
   "java/res/anim/fast_out_slow_in_interpolator.xml",
   "java/res/anim/slide_in_up.xml",
   "java/res/anim/stay_hidden.xml",
-  "java/res/color/tab_layout_colors.xml",
+  "java/res/color/tab_layout_text_color_list.xml",
   "java/res/color/white_mode_tint.xml",
   "java/res/drawable-hdpi/amex_card.png",
   "java/res/drawable-hdpi/bg_tabstrip_background_tab_outline.9.png",
@@ -506,6 +506,7 @@
   "java/res/drawable/ic_select_window.xml",
   "java/res/drawable/ic_signout_40dp.xml",
   "java/res/drawable/ic_site_timer.xml",
+  "java/res/drawable/ic_storefront_blue.xml",
   "java/res/drawable/ic_sync_badge_error_20dp.xml",
   "java/res/drawable/ic_sync_error_48dp.xml",
   "java/res/drawable/ic_sync_error_legacy_40dp.xml",
diff --git a/chrome/android/chrome_public_apk_tmpl.gni b/chrome/android/chrome_public_apk_tmpl.gni
index 9c5ae20..5ed1e35 100644
--- a/chrome/android/chrome_public_apk_tmpl.gni
+++ b/chrome/android/chrome_public_apk_tmpl.gni
@@ -22,6 +22,7 @@
   "channel=$android_channel",
   "enable_vr=$enable_vr",
   "include_arcore_manifest_flag=false",
+  "zygote_preload_class=org.chromium.content_public.app.ZygotePreload",
 ]
 
 # Enable stack unwinding only on official build with specific channels. It is
diff --git a/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected b/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected
index fea5945..e03f4d8 100644
--- a/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected
+++ b/chrome/android/expectations/monochrome_public_bundle.AndroidManifest.expected
@@ -85,7 +85,7 @@
       android:roundIcon="@drawable/ic_launcher_round"
       android:supportsRtl="true"
       android:use32bitAbi="true"
-      android:zygotePreloadName="org.chromium.content.app.ZygotePreload">
+      android:zygotePreloadName="org.chromium.content_public.app.ZygotePreload">
     <activity  # DIFF-ANCHOR: ea1a94af
         android:name="com.google.android.gms.common.api.GoogleApiActivity"
         android:exported="false"
diff --git a/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected b/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected
index 1643eb9..c472e557 100644
--- a/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected
+++ b/chrome/android/expectations/trichrome_chrome_bundle.AndroidManifest.expected
@@ -85,7 +85,7 @@
       android:roundIcon="@drawable/ic_launcher_round"
       android:supportsRtl="true"
       android:use32bitAbi="true"
-      android:zygotePreloadName="org.chromium.content.app.ZygotePreload">
+      android:zygotePreloadName="org.chromium.chrome.app.TrichromeZygotePreload">
     <activity  # DIFF-ANCHOR: ea1a94af
         android:name="com.google.android.gms.common.api.GoogleApiActivity"
         android:exported="false"
diff --git a/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml b/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml
index 763ba7a..6322af5 100644
--- a/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml
+++ b/chrome/android/features/start_surface/internal/java/res/layout/ss_bottom_bar_layout.xml
@@ -24,7 +24,7 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_marginTop="@dimen/toolbar_shadow_height"
-        app:tabIndicatorColor="@color/default_control_color_active"
+        app:tabIndicatorColor="?attr/default_icon_color_accent1"
         app:tabGravity="fill"
         app:tabMode="fixed"
         app:tabMaxWidth="2000dp">
diff --git a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java
index a7d5e3b4..cd448c11 100644
--- a/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java
+++ b/chrome/android/features/vr/java/src/org/chromium/chrome/browser/vr/VrShell.java
@@ -602,7 +602,8 @@
     public void showPageInfo() {
         Tab tab = mCurrentTabSupplier.get();
         if (tab == null) return;
-        new ChromePageInfo(mModalDialogManagerSupplier, null, OpenedFromSource.VR)
+        new ChromePageInfo(mModalDialogManagerSupplier, null, OpenedFromSource.VR,
+                /*storeInfoActionHandlerSupplier=*/null)
                 .show(tab, PageInfoController.NO_HIGHLIGHTED_PERMISSION);
     }
 
diff --git a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceScopeDependencyProvider.java b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceScopeDependencyProvider.java
index 553f8f2..066edf53 100644
--- a/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceScopeDependencyProvider.java
+++ b/chrome/android/feed/core/java/src/org/chromium/chrome/browser/feed/FeedSurfaceScopeDependencyProvider.java
@@ -12,24 +12,17 @@
 import org.chromium.base.Log;
 import org.chromium.base.ObserverList;
 import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.feed.v2.FeedProcessScopeDependencyProvider;
 import org.chromium.chrome.browser.ntp.ScrollListener;
 import org.chromium.chrome.browser.ntp.ScrollListener.ScrollState;
-import org.chromium.chrome.browser.profiles.Profile;
-import org.chromium.chrome.browser.signin.services.IdentityServicesProvider;
 import org.chromium.chrome.browser.xsurface.SurfaceHeaderOffsetObserver;
 import org.chromium.chrome.browser.xsurface.SurfaceScopeDependencyProvider;
-import org.chromium.components.signin.base.CoreAccountInfo;
-import org.chromium.components.signin.identitymanager.ConsentLevel;
 
 /**
  * Provides activity, darkmode and logging context for a single surface.
  */
-@JNINamespace("feed::android")
 class FeedSurfaceScopeDependencyProvider implements SurfaceScopeDependencyProvider, ScrollListener {
     private static final String TAG = "Feed";
     private final Activity mActivity;
@@ -152,63 +145,4 @@
         name += partName;
         return name;
     }
-
-    // TODO(iwells): Remove the methods below once internal sources no longer use them.
-    @Override
-    public String getAccountName() {
-        // Don't return account name if there's a signed-out session ID.
-        if (!getSignedOutSessionId().isEmpty()) {
-            return "";
-        }
-        assert ThreadUtils.runningOnUiThread();
-        CoreAccountInfo primaryAccount =
-                IdentityServicesProvider.get()
-                        .getIdentityManager(Profile.getLastUsedRegularProfile())
-                        .getPrimaryAccountInfo(ConsentLevel.SIGNIN);
-        return (primaryAccount == null) ? "" : primaryAccount.getEmail();
-    }
-
-    @Override
-    public String getClientInstanceId() {
-        // Don't return client instance id if there's a signed-out session ID.
-        if (!getSignedOutSessionId().isEmpty()) {
-            return "";
-        }
-        assert ThreadUtils.runningOnUiThread();
-        return FeedServiceBridge.getClientInstanceId();
-    }
-
-    @Override
-    public int[] getExperimentIds() {
-        assert ThreadUtils.runningOnUiThread();
-        return FeedSurfaceScopeDependencyProviderJni.get().getExperimentIds();
-    }
-
-    @Override
-    public String getSignedOutSessionId() {
-        ThreadUtils.runningOnUiThread();
-        return FeedSurfaceScopeDependencyProviderJni.get().getSessionId();
-    }
-
-    /**
-     * Stores a view FeedAction for eventual upload. 'data' is a serialized FeedAction protobuf
-     * message.
-     */
-    @Override
-    public void processViewAction(byte[] data) {
-        FeedSurfaceScopeDependencyProviderJni.get().processViewAction(data);
-    }
-
-    @Override
-    public void reportOnUploadVisibilityLog(boolean success) {
-        RecordHistogram.recordBooleanHistogram(
-                "ContentSuggestions.Feed.UploadVisibilityLog", success);
-    }
-
-    @NativeMethods
-    interface Natives {
-        int[] getExperimentIds();
-        String getSessionId();
-        void processViewAction(byte[] data);
-    }
 }
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index e1987b18..260bb164 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -177,7 +177,7 @@
         android:largeHeap="false"
         android:manageSpaceActivity="@string/manage_space_activity"
         android:supportsRtl="true"
-        android:zygotePreloadName="org.chromium.content.app.ZygotePreload"
+        android:zygotePreloadName="{{ zygote_preload_class }}"
         {% if backup_key is defined %}
         android:allowBackup="true"
         android:backupAgent="org.chromium.chrome.browser.ChromeBackupAgent"
diff --git a/chrome/android/java/res/color/tab_layout_colors.xml b/chrome/android/java/res/color/tab_layout_colors.xml
deleted file mode 100644
index 495dd2b..0000000
--- a/chrome/android/java/res/color/tab_layout_colors.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright 2021 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.
--->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-  <item android:alpha="@dimen/default_disabled_alpha"
-      android:color="@color/default_text_color_secondary" android:state_enabled="false"/>
-  <item android:color="@color/tab_layout_selected_tab_color" android:state_selected="true"/>
-  <item android:color="@color/default_text_color_secondary" />
-</selector>
diff --git a/chrome/android/java/res/color/tab_layout_text_color_list.xml b/chrome/android/java/res/color/tab_layout_text_color_list.xml
new file mode 100644
index 0000000..6952402a
--- /dev/null
+++ b/chrome/android/java/res/color/tab_layout_text_color_list.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+  <item android:alpha="@dimen/default_disabled_alpha"
+      android:color="?attr/colorOnSurfaceVariant" android:state_enabled="false"/>
+  <item android:color="?attr/default_text_color_accent1" android:state_selected="true"/>
+  <item android:color="?attr/colorOnSurfaceVariant" />
+</selector>
diff --git a/chrome/android/java/res/drawable/ic_storefront_blue.xml b/chrome/android/java/res/drawable/ic_storefront_blue.xml
new file mode 100644
index 0000000..7f1cd8b
--- /dev/null
+++ b/chrome/android/java/res/drawable/ic_storefront_blue.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 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. -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:viewportWidth="24"
+    android:viewportHeight="24">
+  <path
+      android:pathData="m21.9,8.89 l-1.05,-4.37c-0.22,-0.9 -1,-1.52 -1.91,-1.52L5.05,3c-0.9,0 -1.69,0.63 -1.9,1.52L2.1,8.89c-0.24,1.02 -0.02,2.06 0.62,2.88 0.08,0.11 0.19,0.19 0.28,0.29L3,19c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2v-6.94c0.09,-0.09 0.2,-0.18 0.28,-0.28 0.64,-0.82 0.87,-1.87 0.62,-2.89ZM18.91,4.99 L19.96,9.36c0.1,0.42 0.01,0.84 -0.25,1.17 -0.14,0.18 -0.44,0.47 -0.94,0.47 -0.61,0 -1.14,-0.49 -1.21,-1.14L16.98,5l1.93,-0.01ZM13,5h1.96l0.54,4.52c0.05,0.39 -0.07,0.78 -0.33,1.07 -0.22,0.26 -0.54,0.41 -0.95,0.41 -0.67,0 -1.22,-0.59 -1.22,-1.31L13,5ZM8.49,9.52 L9.04,5L11,5v4.69c0,0.72 -0.55,1.31 -1.29,1.31 -0.34,0 -0.65,-0.15 -0.89,-0.41a1.42,1.42 0,0 1,-0.33 -1.07ZM4.04,9.36L5.05,5h1.97l-0.58,4.86c-0.08,0.65 -0.6,1.14 -1.21,1.14 -0.49,0 -0.8,-0.29 -0.93,-0.47 -0.27,-0.32 -0.36,-0.75 -0.26,-1.17ZM5,19v-6.03c0.08,0.01 0.15,0.03 0.23,0.03 0.87,0 1.66,-0.36 2.24,-0.95 0.6,0.6 1.4,0.95 2.31,0.95 0.87,0 1.65,-0.36 2.23,-0.93 0.59,0.57 1.39,0.93 2.29,0.93 0.84,0 1.64,-0.35 2.24,-0.95 0.58,0.59 1.37,0.95 2.24,0.95 0.08,0 0.15,-0.02 0.23,-0.03L19.01,19L5,19Z"
+      android:fillColor="?attr/default_icon_color_blue" />
+</vector>
diff --git a/chrome/android/java/res/layout/clear_browsing_data_tabs.xml b/chrome/android/java/res/layout/clear_browsing_data_tabs.xml
index 5dec369f..d5a91a5 100644
--- a/chrome/android/java/res/layout/clear_browsing_data_tabs.xml
+++ b/chrome/android/java/res/layout/clear_browsing_data_tabs.xml
@@ -16,6 +16,8 @@
         android:id="@+id/clear_browsing_data_tabs"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        app:tabPaddingStart="5dp"
+        app:tabPaddingEnd="5dp"
         style="@style/TabLayoutStyle" />
 
     <androidx.viewpager2.widget.ViewPager2
diff --git a/chrome/android/java/res/layout/infobar_translate_compact_content.xml b/chrome/android/java/res/layout/infobar_translate_compact_content.xml
index 890a0f5..9b0c8da6 100644
--- a/chrome/android/java/res/layout/infobar_translate_compact_content.xml
+++ b/chrome/android/java/res/layout/infobar_translate_compact_content.xml
@@ -10,7 +10,6 @@
     android:layout_height="wrap_content"
     android:gravity="center_vertical"
     android:orientation="horizontal">
-    <!-- TODO(huayinz): Change app:tabIndicatorColor to some common color reference -->
     <org.chromium.components.translate.TranslateTabLayout
         android:id="@+id/translate_infobar_tabs"
         android:layout_width="0dp"
@@ -18,14 +17,8 @@
         android:layout_weight="1"
         android:requiresFadingEdge="horizontal"
         android:fadingEdgeLength="@dimen/infobar_translate_fade_edge_length"
-        app:tabIndicator="@drawable/tab_indicator"
-        app:tabIndicatorFullWidth="false"
-        app:tabIndicatorHeight="3dp"
-        app:tabSelectedTextColor="@color/tab_layout_selected_tab_color"
-        app:tabIndicatorColor="@color/tab_layout_selected_tab_color"
-        app:tabGravity="fill"
-        android:background="@android:color/transparent"
-        app:tabMode="scrollable" />
+        app:tabMode="scrollable"
+        style="@style/TabLayoutStyle"/>
 
     <org.chromium.ui.widget.ChromeImageButton
         android:id="@+id/translate_infobar_menu_button"
diff --git a/chrome/android/java/res/layout/new_tab_page_multi_feed_header.xml b/chrome/android/java/res/layout/new_tab_page_multi_feed_header.xml
index 3ae5674d..b7367f7 100644
--- a/chrome/android/java/res/layout/new_tab_page_multi_feed_header.xml
+++ b/chrome/android/java/res/layout/new_tab_page_multi_feed_header.xml
@@ -34,7 +34,6 @@
         android:visibility="invisible"
         android:layout_marginEnd="@dimen/feed_header_icon_margin"
         app:tint="?attr/default_icon_color_disabled"
-        android:tintMode="src_in"
         tools:ignore="contentDescription" />
 
     <com.google.android.material.tabs.TabLayout
diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml
index bf25c46..bd1bcf60 100644
--- a/chrome/android/java/res/values/styles.xml
+++ b/chrome/android/java/res/values/styles.xml
@@ -293,32 +293,29 @@
     </style>
 
     <!-- Tab Layout -->
-    <style name="TabLayoutStyle">
+    <style name="TabLayoutStyle" parent="Widget.MaterialComponents.TabLayout">
+        <item name="android:background">@android:color/transparent</item>
         <item name="tabIndicator">@drawable/tab_indicator</item>
+        <item name="tabIndicatorColor">?attr/default_icon_color_accent1</item>
         <item name="tabIndicatorFullWidth">false</item>
         <item name="tabIndicatorHeight">@dimen/tab_indicator_height</item>
-        <item name="tabPaddingStart">5dp</item>
-        <item name="tabPaddingEnd">5dp</item>
         <item name="tabMode">fixed</item>
         <item name="tabGravity">fill</item>
         <item name="tabMaxWidth">0dp</item>
         <item name="tabTextAppearance">@style/TextAppearance.TextMediumThick</item>
-        <item name="tabTextColor">@color/default_text_color_secondary</item>
-        <item name="tabSelectedTextColor">@color/tab_layout_selected_tab_color</item>
-        <item name="android:background">@color/default_bg_color</item>
+        <item name="tabTextColor">@color/default_text_color_secondary_list</item>
+        <item name="tabSelectedTextColor">?attr/default_text_color_accent1</item>
     </style>
 
     <style name="NtpHeaderTabLayoutStyle" parent="TabLayoutStyle">
-        <item name="tabIndicatorColor">?attr/default_icon_color_blue</item>
         <item name="tabTextAppearance">@style/TextAppearance.TextAccentMediumThick</item>
         <item name="tabGravity">center</item>
-        <item name="android:background">@android:color/transparent</item>
         <item name="tabPaddingEnd">7dp</item>
         <item name="tabPaddingStart">7dp</item>
     </style>
 
     <style name="TextAppearance.TabLayout" parent="TextAppearance.TextAccentMediumThick">
-      <item name="android:textColor">@color/tab_layout_colors</item>
+      <item name="android:textColor">@color/tab_layout_text_color_list</item>
     </style>
 
     <!-- Misc styles -->
diff --git a/chrome/android/java/src/org/chromium/chrome/app/TrichromeZygotePreload.java b/chrome/android/java/src/org/chromium/chrome/app/TrichromeZygotePreload.java
new file mode 100644
index 0000000..4745eb4
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/app/TrichromeZygotePreload.java
@@ -0,0 +1,24 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.app;
+
+import android.content.pm.ApplicationInfo;
+
+import org.chromium.base.library_loader.LibraryLoader;
+import org.chromium.chrome.browser.ProductConfig;
+import org.chromium.content_public.app.ZygotePreload;
+
+/**
+ * The {@link ZygotePreload} allowing to use the ModernLinker when running Trichrome.
+ */
+public class TrichromeZygotePreload extends ZygotePreload {
+    @Override
+    public void doPreload(ApplicationInfo appInfo) {
+        // The ModernLinker is only needed when the App Zygote intends to create the RELRO region.
+        boolean useModernLinker = ProductConfig.USE_MODERN_LINKER
+                && !LibraryLoader.mainProcessIntendsToProvideRelroFd();
+        doPreloadCommon(appInfo, useModernLinker);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
index 8ec37159..9e50178 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
@@ -109,6 +109,9 @@
         super.onConfigurationChanged(newConfig);
         NightModeUtils.updateConfigurationForNightMode(
                 this, mNightModeStateProvider.isInNightMode(), newConfig, mThemeResId);
+        // newConfig will have the default system locale so reapply the app locale override if
+        // needed: https://crbug.com/1248944
+        GlobalAppLocaleController.getInstance().maybeOverrideContextConfig(this);
     }
 
     // Implementation of ModalDialogManagerHolder
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 487c7e3..9caad96 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -508,7 +508,7 @@
                 getTabContentManagerSupplier(), getOverviewModeBehaviorSupplier(),
                 this::getSnackbarManager, getActivityType(), this::isInOverviewMode,
                 this::isWarmOnResume, /* appMenuDelegate= */ this,
-                /* statusBarColorProvider= */ this);
+                /* statusBarColorProvider= */ this, getIntentRequestTracker());
         // clang-format on
     }
 
@@ -2441,8 +2441,8 @@
         }
 
         if (id == R.id.info_menu_id) {
-            ChromePageInfo pageInfo = new ChromePageInfo(
-                    getModalDialogManagerSupplier(), null, OpenedFromSource.MENU);
+            ChromePageInfo pageInfo = new ChromePageInfo(getModalDialogManagerSupplier(), null,
+                    OpenedFromSource.MENU, mRootUiCoordinator.getStoreInfoActionHandlerSupplier());
             pageInfo.show(currentTab, PageInfoController.NO_HIGHLIGHTED_PERMISSION);
             return true;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java
index 22cf1f8..420c833b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/ToolbarSwipeLayout.java
@@ -453,8 +453,8 @@
         if (mSceneLayer != null) {
             int background_color = getBackgroundColor();
 
-            if (mLeftTab != null) mSceneLayer.update(mLeftTab, true, background_color);
-            if (mRightTab != null) mSceneLayer.update(mRightTab, false, background_color);
+            mSceneLayer.update(mLeftTab, true, background_color);
+            mSceneLayer.update(mRightTab, false, background_color);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSwipeSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSwipeSceneLayer.java
index 0f9b1d1..608efc1 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSwipeSceneLayer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/ToolbarSwipeSceneLayer.java
@@ -11,6 +11,7 @@
 import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
 import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
 import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer;
+import org.chromium.chrome.browser.tab.Tab;
 
 /** A SceneLayer that displays one or two tab content layers for toolbar swipe functionality. */
 @JNINamespace("android")
@@ -24,13 +25,13 @@
     }
 
     public void update(LayoutTab tab, boolean isLeftTab, int backgroundColor) {
-        if (tab == null) return;
-
         final float dpToPx = mContext.getResources().getDisplayMetrics().density;
 
-        ToolbarSwipeSceneLayerJni.get().updateLayer(mNativePtr, this, tab.get(LayoutTab.TAB_ID),
-                isLeftTab, tab.get(LayoutTab.CAN_USE_LIVE_TEXTURE), backgroundColor,
-                tab.get(LayoutTab.X) * dpToPx, tab.get(LayoutTab.Y) * dpToPx);
+        ToolbarSwipeSceneLayerJni.get().updateLayer(mNativePtr, this,
+                tab != null ? tab.get(LayoutTab.TAB_ID) : Tab.INVALID_TAB_ID, isLeftTab,
+                tab != null ? tab.get(LayoutTab.CAN_USE_LIVE_TEXTURE) : false, backgroundColor,
+                tab != null ? tab.get(LayoutTab.X) * dpToPx : 0,
+                tab != null ? tab.get(LayoutTab.Y) * dpToPx : 0);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
index b65aab3c..6e14ba0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -161,7 +161,7 @@
                 getOverviewModeBehaviorSupplier(), this::getSnackbarManager, getActivityType(),
                 this::isInOverviewMode, this::isWarmOnResume,
                 /* appMenuDelegate= */ this, /* statusBarColorProvider= */ this,
-                () -> mToolbarCoordinator, () -> mNavigationController);
+                getIntentRequestTracker(), () -> mToolbarCoordinator, () -> mNavigationController);
         // clang-format on
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
index 8b3ebbd..527561e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -42,6 +42,7 @@
 import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController;
 import org.chromium.components.feature_engagement.Tracker;
 import org.chromium.ui.base.ActivityWindowAndroid;
+import org.chromium.ui.base.IntentRequestTracker;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 
 /**
@@ -81,6 +82,7 @@
      * @param isWarmOnResumeSupplier Supplies whether the app was warm on resume.
      * @param appMenuDelegate The app menu delegate.
      * @param statusBarColorProvider Provides the status bar color.
+     * @param intentRequestTracker Tracks intent requests.
      * @param customTabToolbarCoordinator Coordinates the custom tab toolbar.
      * @param customTabNavigationController Controls the custom tab navigation.
      */
@@ -111,6 +113,7 @@
             @NonNull Supplier<Boolean> isWarmOnResumeSupplier,
             @NonNull AppMenuDelegate appMenuDelegate,
             @NonNull StatusBarColorProvider statusBarColorProvider,
+            @NonNull IntentRequestTracker intentRequestTracker,
             @NonNull Supplier<CustomTabToolbarCoordinator> customTabToolbarCoordinator,
             @NonNull Supplier<CustomTabActivityNavigationController>
                     customTabNavigationController) {
@@ -126,7 +129,7 @@
                 fullscreenManager, compositorViewHolderSupplier, tabContentManagerSupplier,
                 overviewModeBehaviorSupplier, snackbarManagerSupplier, activityType,
                 isInOverviewModeSupplier, isWarmOnResumeSupplier, appMenuDelegate,
-                statusBarColorProvider);
+                statusBarColorProvider, intentRequestTracker);
         // clang-format on
         mToolbarCoordinator = customTabToolbarCoordinator;
         mNavigationController = customTabNavigationController;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
index 57b21c7..d67f38e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -217,7 +217,8 @@
             Tab tab = getTabModelSelector().getCurrentTab();
             if (tab == null) return false;
             String publisher = getToolbarManager().getContentPublisher();
-            new ChromePageInfo(getModalDialogManagerSupplier(), publisher, OpenedFromSource.MENU)
+            new ChromePageInfo(getModalDialogManagerSupplier(), publisher, OpenedFromSource.MENU,
+                    mRootUiCoordinator.getStoreInfoActionHandlerSupplier())
                     .show(tab, PageInfoController.NO_HIGHLIGHTED_PERMISSION);
             return true;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java
index a0cceea..b684a15 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/toolbar/CustomTabToolbar.java
@@ -726,8 +726,9 @@
                 if (webContents == null) return;
                 Activity activity = currentTab.getWindowAndroid().getActivity().get();
                 if (activity == null) return;
+                // For now we don't show "store info" row for custom tab.
                 new ChromePageInfo(mModalDialogManagerSupplier, getContentPublisher(),
-                        OpenedFromSource.TOOLBAR)
+                        OpenedFromSource.TOOLBAR, /*storeInfoActionHandlerSupplier=*/null)
                         .show(currentTab, PageInfoController.NO_HIGHLIGHTED_PERMISSION);
             });
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfo.java
index 8d22188..c6ce3f3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfo.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfo.java
@@ -10,6 +10,7 @@
 import androidx.annotation.Nullable;
 
 import org.chromium.base.supplier.Supplier;
+import org.chromium.chrome.browser.merchant_viewer.PageInfoStoreInfoController.StoreInfoActionHandler;
 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabUtils;
@@ -26,17 +27,21 @@
     private final @NonNull Supplier<ModalDialogManager> mModalDialogManagerSupplier;
     private final @Nullable String mPublisher;
     private final @OpenedFromSource int mSource;
+    private final @Nullable Supplier<StoreInfoActionHandler> mStoreInfoActionHandlerSupplier;
 
     /**
      * @param modalDialogManagerSupplier Supplier of modal dialog manager.
      * @param publisher The name of the publisher of the content.
      * @param source the source that triggered the popup.
+     * @param storeInfoActionHandlerSupplier Supplier of {@link StoreInfoActionHandler}.
      */
     public ChromePageInfo(@NonNull Supplier<ModalDialogManager> modalDialogManagerSupplier,
-            @Nullable String publisher, @OpenedFromSource int source) {
+            @Nullable String publisher, @OpenedFromSource int source,
+            @Nullable Supplier<StoreInfoActionHandler> storeInfoActionHandlerSupplier) {
         mModalDialogManagerSupplier = modalDialogManagerSupplier;
         mPublisher = publisher;
         mSource = source;
+        mStoreInfoActionHandlerSupplier = storeInfoActionHandlerSupplier;
     }
 
     /**
@@ -50,7 +55,8 @@
         PageInfoController.show(activity, webContents, mPublisher, mSource,
                 new ChromePageInfoControllerDelegate(activity, webContents,
                         mModalDialogManagerSupplier,
-                        new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)),
+                        new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab),
+                        mStoreInfoActionHandlerSupplier),
                 permission);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java
index 0e105e5..be5d3b20 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/page_info/ChromePageInfoControllerDelegate.java
@@ -24,6 +24,8 @@
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.feature_engagement.TrackerFactory;
 import org.chromium.chrome.browser.instantapps.InstantAppsHandler;
+import org.chromium.chrome.browser.merchant_viewer.PageInfoStoreInfoController;
+import org.chromium.chrome.browser.merchant_viewer.PageInfoStoreInfoController.StoreInfoActionHandler;
 import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils;
 import org.chromium.chrome.browser.offlinepages.OfflinePageUtils.OfflinePageLoadUrlDelegate;
@@ -71,12 +73,14 @@
     private Supplier<ModalDialogManager> mModalDialogManagerSupplier;
     private final Context mContext;
     private final Profile mProfile;
+    private final Supplier<StoreInfoActionHandler> mStoreInfoActionHandlerSupplier;
     private String mOfflinePageCreationDate;
     private OfflinePageLoadUrlDelegate mOfflinePageLoadUrlDelegate;
 
     public ChromePageInfoControllerDelegate(Context context, WebContents webContents,
             Supplier<ModalDialogManager> modalDialogManagerSupplier,
-            OfflinePageLoadUrlDelegate offlinePageLoadUrlDelegate) {
+            OfflinePageLoadUrlDelegate offlinePageLoadUrlDelegate,
+            @Nullable Supplier<StoreInfoActionHandler> storeInfoActionHandlerSupplier) {
         super(new ChromeAutocompleteSchemeClassifier(Profile.fromWebContents(webContents)),
                 VrModuleProvider.getDelegate(),
                 /** isSiteSettingsAvailable= */
@@ -87,6 +91,7 @@
         mWebContents = webContents;
         mModalDialogManagerSupplier = modalDialogManagerSupplier;
         mProfile = Profile.fromWebContents(mWebContents);
+        mStoreInfoActionHandlerSupplier = storeInfoActionHandlerSupplier;
 
         initOfflinePageParams();
         mOfflinePageLoadUrlDelegate = offlinePageLoadUrlDelegate;
@@ -232,6 +237,13 @@
             controllers.add(new PageInfoHistoryController(
                     mainController, historyRow, this, () -> { return tab; }));
         }
+        if (PageInfoFeatures.PAGE_INFO_STORE_INFO.isEnabled()) {
+            final PageInfoRowView storeInfoRow = new PageInfoRowView(rowWrapper.getContext(), null);
+            storeInfoRow.setId(PageInfoStoreInfoController.STORE_INFO_ROW_ID);
+            rowWrapper.addView(storeInfoRow);
+            controllers.add(new PageInfoStoreInfoController(
+                    mainController, storeInfoRow, mStoreInfoActionHandlerSupplier));
+        }
         return controllers;
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java
index 52f2c04..52f2e73 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/handler/toolbar/PaymentHandlerToolbarCoordinator.java
@@ -144,12 +144,16 @@
     }
 
     private void showPageInfoDialog() {
+        // When creating the {@link ChromePageInfoControllerDelegate} here, we don't need
+        // storeInfoActionHandlerSupplier and don't show "store info" row because this UI is already
+        // in a bottom sheet and clicking "store info" row would trigger another bottom sheet.
         PageInfoController.show(mActivity, mWebContents, null,
                 PageInfoController.OpenedFromSource.TOOLBAR,
                 new ChromePageInfoControllerDelegate(mActivity, mWebContents,
                         mModalDialogManagerSupplier,
                         /*offlinePageLoadUrlDelegate=*/
-                        new OfflinePageUtils.WebContentsOfflinePageLoadUrlDelegate(mWebContents)),
+                        new OfflinePageUtils.WebContentsOfflinePageLoadUrlDelegate(mWebContents),
+                        /*storeInfoActionHandlerSupplier=*/null),
                 PageInfoController.NO_HIGHLIGHTED_PERMISSION);
     }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
index c63801c..6061bed 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -61,8 +61,6 @@
 import org.chromium.chrome.browser.layouts.LayoutStateProvider;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.locale.LocaleManager;
-import org.chromium.chrome.browser.merchant_viewer.MerchantTrustMetrics;
-import org.chromium.chrome.browser.merchant_viewer.MerchantTrustSignalsCoordinator;
 import org.chromium.chrome.browser.multiwindow.MultiWindowUtils;
 import org.chromium.chrome.browser.ntp.NewTabPageLaunchOrigin;
 import org.chromium.chrome.browser.ntp.NewTabPageUtils;
@@ -153,11 +151,9 @@
     private HeightObserver mContinuousSearchObserver;
     private TabObscuringHandler.Observer mContinuousSearchTabObscuringHandlerObserver;
     private FindToolbarObserver mContinuousSearchFindToolbarObserver;
-    private MerchantTrustSignalsCoordinator mMerchantTrustSignalsCoordinator;
     private @Nullable ScrollCaptureManager mScrollCaptureManager;
     private CommerceSubscriptionsService mCommerceSubscriptionsService;
     private UndoGroupSnackbarController mUndoGroupSnackbarController;
-    private final IntentRequestTracker mIntentRequestTracker;
     private final int mControlContainerHeightResource;
     private final Supplier<InsetObserverView> mInsetObserverViewSupplier;
     private final Function<Tab, Boolean> mBackButtonShouldCloseTabFn;
@@ -289,9 +285,8 @@
                 compositorViewHolderSupplier, tabContentManagerSupplier,
                 overviewModeBehaviorSupplier, snackbarManagerSupplier, activityType,
                 isInOverviewModeSupplier, isWarmOnResumeSupplier, appMenuDelegate,
-                statusBarColorProvider);
+                statusBarColorProvider, intentRequestTracker);
         mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier;
-        mIntentRequestTracker = intentRequestTracker;
         mControlContainerHeightResource = controlContainerHeightResource;
         mInsetObserverViewSupplier = insetObserverViewSupplier;
         mBackButtonShouldCloseTabFn = backButtonShouldCloseTabFn;
@@ -374,11 +369,6 @@
             mUndoGroupSnackbarController.destroy();
         }
 
-        if (mMerchantTrustSignalsCoordinator != null) {
-            mMerchantTrustSignalsCoordinator.destroy();
-            mMerchantTrustSignalsCoordinator = null;
-        }
-
         if (mCommerceSubscriptionsService != null) {
             mCommerceSubscriptionsService.destroy();
             mCommerceSubscriptionsService = null;
@@ -518,7 +508,6 @@
         PwaBottomSheetControllerFactory.attach(mWindowAndroid, mPwaBottomSheetController);
         initContinuousSearchCoordinator();
         initScrollCapture();
-        initMerchantTrustSignals();
         initCommerceSubscriptionsService();
         initUndoGroupSnackbarController();
     }
@@ -529,17 +518,6 @@
                 == StartSurfaceState.SHOWN_HOMEPAGE;
     }
 
-    private void initMerchantTrustSignals() {
-        if (!ChromeFeatureList.isEnabled(ChromeFeatureList.COMMERCE_MERCHANT_VIEWER)) {
-            return;
-        }
-
-        mMerchantTrustSignalsCoordinator = new MerchantTrustSignalsCoordinator(mActivity,
-                mWindowAndroid, getBottomSheetController(), mActivity.getWindow().getDecorView(),
-                MessageDispatcherProvider.from(mWindowAndroid), mActivityTabProvider,
-                mProfileSupplier, new MerchantTrustMetrics(), mIntentRequestTracker);
-    }
-
     private void initScrollCapture() {
         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S
                 || !ChromeFeatureList.isEnabled(ChromeFeatureList.SCROLL_CAPTURE)) {
@@ -565,6 +543,11 @@
     }
 
     @Override
+    protected boolean shouldInitializeMerchantTrustSignals() {
+        return true;
+    }
+
+    @Override
     protected ScrimCoordinator buildScrimWidget() {
         ViewGroup coordinator = mActivity.findViewById(R.id.coordinator);
         ScrimCoordinator.SystemUiScrimDelegate delegate =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index 8a427a3..69d0ef6d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -71,6 +71,7 @@
 import org.chromium.chrome.browser.layouts.LayoutStateProvider;
 import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
+import org.chromium.chrome.browser.merchant_viewer.PageInfoStoreInfoController.StoreInfoActionHandler;
 import org.chromium.chrome.browser.ntp.IncognitoNewTabPage;
 import org.chromium.chrome.browser.ntp.NewTabPage;
 import org.chromium.chrome.browser.ntp.NewTabPageUma;
@@ -360,6 +361,7 @@
      * @param tabCreatorManager Manages the creation of tabs.
      * @param overviewModeBehaviorSupplier Supplies the current {@link OverviewModeBehavior}.
      * @param snackbarManager Manages the display of snackbars.
+     * @param storeInfoActionHandlerSupplier Supplier of {@link StoreInfoActionHandler}.
      */
     public ToolbarManager(AppCompatActivity activity, BrowserControlsSizer controlsSizer,
             FullscreenManager fullscreenManager, ToolbarControlContainer controlContainer,
@@ -391,7 +393,8 @@
             @NonNull TabContentManager tabContentManager,
             @NonNull TabCreatorManager tabCreatorManager,
             @NonNull OneshotSupplier<OverviewModeBehavior> overviewModeBehaviorSupplier,
-            @NonNull SnackbarManager snackbarManager, JankTracker jankTracker) {
+            @NonNull SnackbarManager snackbarManager, JankTracker jankTracker,
+            Supplier<StoreInfoActionHandler> storeInfoActionHandlerSupplier) {
         TraceEvent.begin("ToolbarManager.ToolbarManager");
         mActivity = activity;
         mWindowAndroid = windowAndroid;
@@ -561,8 +564,8 @@
                     -> ReturnToChromeExperimentsUtil.handleLoadUrlWithPostDataFromStartSurface(
                             new LoadUrlParams(url, transition | PageTransition.FROM_ADDRESS_BAR),
                             postDataType, postData, incognito, startSurfaceParentTabSupplier.get());
-            ChromePageInfo toolbarPageInfo =
-                    new ChromePageInfo(modalDialogManagerSupplier, null, OpenedFromSource.TOOLBAR);
+            ChromePageInfo toolbarPageInfo = new ChromePageInfo(modalDialogManagerSupplier, null,
+                    OpenedFromSource.TOOLBAR, storeInfoActionHandlerSupplier);
             ExploreIconProvider exploreIconProvider = (pixelSize, callback) -> {
                 if (profileSupplier.get() != null) {
                     ExploreSitesBridge.getSummaryImage(profileSupplier.get(), pixelSize, callback);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
index 5b3b6ac4..90f024ec 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -62,6 +62,9 @@
 import org.chromium.chrome.browser.lifecycle.DestroyObserver;
 import org.chromium.chrome.browser.lifecycle.InflationObserver;
 import org.chromium.chrome.browser.lifecycle.NativeInitObserver;
+import org.chromium.chrome.browser.merchant_viewer.MerchantTrustMetrics;
+import org.chromium.chrome.browser.merchant_viewer.MerchantTrustSignalsCoordinator;
+import org.chromium.chrome.browser.merchant_viewer.PageInfoStoreInfoController.StoreInfoActionHandler;
 import org.chromium.chrome.browser.messages.ChromeMessageAutodismissDurationProvider;
 import org.chromium.chrome.browser.messages.ChromeMessageQueueMediator;
 import org.chromium.chrome.browser.messages.MessageContainerCoordinator;
@@ -120,12 +123,14 @@
 import org.chromium.components.messages.DismissReason;
 import org.chromium.components.messages.ManagedMessageDispatcher;
 import org.chromium.components.messages.MessageContainer;
+import org.chromium.components.messages.MessageDispatcherProvider;
 import org.chromium.components.messages.MessagesFactory;
 import org.chromium.components.ukm.UkmRecorder;
 import org.chromium.content_public.browser.ActionModeCallbackHelper;
 import org.chromium.content_public.browser.LoadUrlParams;
 import org.chromium.ui.base.ActivityWindowAndroid;
 import org.chromium.ui.base.DeviceFormFactor;
+import org.chromium.ui.base.IntentRequestTracker;
 import org.chromium.ui.base.PageTransition;
 import org.chromium.ui.modaldialog.ModalDialogManager;
 import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogManagerObserver;
@@ -196,6 +201,9 @@
     private final ToolbarActionModeCallback mActionModeControllerCallback;
     private ObservableSupplierImpl<Boolean> mOmniboxFocusStateSupplier =
             new ObservableSupplierImpl<>();
+    private final ObservableSupplierImpl<StoreInfoActionHandler> mStoreInfoActionHandlerSupplier =
+            new ObservableSupplierImpl<>();
+    private MerchantTrustSignalsCoordinator mMerchantTrustSignalsCoordinator;
     protected final ObservableSupplier<Profile> mProfileSupplier;
     private final ObservableSupplier<BookmarkBridge> mBookmarkBridgeSupplier;
     private final OneshotSupplierImpl<AppMenuCoordinator> mAppMenuSupplier;
@@ -237,6 +245,7 @@
     private final AppMenuDelegate mAppMenuDelegate;
     private final StatusBarColorProvider mStatusBarColorProvider;
     private final Supplier<TabContentManager> mTabContentManagerSupplier;
+    private final IntentRequestTracker mIntentRequestTracker;
 
     /**
      * Create a new {@link RootUiCoordinator} for the given activity.
@@ -275,6 +284,7 @@
      * @param isWarmOnResumeSupplier Supplies whether the app was warm on resume.
      * @param appMenuDelegate The app menu delegate.
      * @param statusBarColorProvider Provides the status bar color.
+     * @param intentRequestTracker Tracks intent requests.
      */
     public RootUiCoordinator(@NonNull AppCompatActivity activity,
             @Nullable Callback<Boolean> onOmniboxFocusChangedListener,
@@ -307,7 +317,8 @@
             @ActivityType int activityType, @NonNull Supplier<Boolean> isInOverviewModeSupplier,
             @NonNull Supplier<Boolean> isWarmOnResumeSupplier,
             @NonNull AppMenuDelegate appMenuDelegate,
-            @NonNull StatusBarColorProvider statusBarColorProvider) {
+            @NonNull StatusBarColorProvider statusBarColorProvider,
+            @NonNull IntentRequestTracker intentRequestTracker) {
         mJankTracker = jankTracker;
         mCallbackController = new CallbackController();
         mActivity = activity;
@@ -332,6 +343,7 @@
         mIsWarmOnResumeSupplier = isWarmOnResumeSupplier;
         mAppMenuDelegate = appMenuDelegate;
         mStatusBarColorProvider = statusBarColorProvider;
+        mIntentRequestTracker = intentRequestTracker;
 
         mMenuOrKeyboardActionController = menuOrKeyboardActionController;
         mMenuOrKeyboardActionController.registerMenuOrKeyboardActionHandler(this);
@@ -505,6 +517,12 @@
             mCaptureController = null;
         }
 
+        if (mMerchantTrustSignalsCoordinator != null) {
+            mMerchantTrustSignalsCoordinator.destroy();
+            mMerchantTrustSignalsCoordinator = null;
+            mStoreInfoActionHandlerSupplier.set(null);
+        }
+
         mActivity = null;
     }
 
@@ -623,6 +641,35 @@
         }
         DownloadManagerService.getDownloadManagerService().onActivityLaunched(mActivity,
                 () -> mMessageDispatcher, mModalDialogManagerSupplier.get(), mActivityTabProvider);
+
+        initMerchantTrustSignals();
+    }
+
+    private void initMerchantTrustSignals() {
+        if (ChromeFeatureList.isEnabled(ChromeFeatureList.COMMERCE_MERCHANT_VIEWER)
+                && shouldInitializeMerchantTrustSignals()) {
+            mMerchantTrustSignalsCoordinator =
+                    new MerchantTrustSignalsCoordinator(mActivity, mWindowAndroid,
+                            getBottomSheetController(), mActivity.getWindow().getDecorView(),
+                            MessageDispatcherProvider.from(mWindowAndroid), mActivityTabProvider,
+                            mProfileSupplier, new MerchantTrustMetrics(), mIntentRequestTracker);
+            mStoreInfoActionHandlerSupplier.set(mMerchantTrustSignalsCoordinator);
+        }
+    }
+
+    /**
+     * @return Whether the {@link MerchantTrustSignalsCoordinator} should be initialized in the
+     * context of this coordinator's UI.
+     **/
+    protected boolean shouldInitializeMerchantTrustSignals() {
+        return false;
+    }
+
+    /**
+     * Returns the supplier of {@link StoreInfoActionHandler}.
+     */
+    public Supplier<StoreInfoActionHandler> getStoreInfoActionHandlerSupplier() {
+        return mStoreInfoActionHandlerSupplier;
     }
 
     /**
@@ -855,7 +902,8 @@
                     mActivityLifecycleDispatcher, mStartSurfaceParentTabSupplier,
                     mBottomSheetController, mIsWarmOnResumeSupplier,
                     mTabContentManagerSupplier.get(), mTabCreatorManagerSupplier.get(),
-                    mOverviewModeBehaviorSupplier, mSnackbarManagerSupplier.get(), mJankTracker);
+                    mOverviewModeBehaviorSupplier, mSnackbarManagerSupplier.get(), mJankTracker,
+                    getStoreInfoActionHandlerSupplier());
             if (!mSupportsAppMenuSupplier.getAsBoolean()) {
                 mToolbarManager.getToolbar().disableMenuButton();
             }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
index 622fdb9c..dc6d560 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ShareIntentTest.java
@@ -160,7 +160,8 @@
                     mockActivity::getSnackbarManager, mockActivity.getActivityType(),
                     mockActivity::isInOverviewMode, mockActivity::isWarmOnResume,
                     /* appMenuDelegate= */ mockActivity,
-                    /* statusBarColorProvider= */ mockActivity);
+                    /* statusBarColorProvider= */ mockActivity,
+                    mockActivity.getIntentRequestTracker());
 
             ShareHelper.setLastShareComponentName(
                     null, new ComponentName("test.package", "test.activity"));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java
index c42b4159..e0438c7 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewDarkModeTest.java
@@ -80,7 +80,7 @@
         Tab tab = activity.getActivityTab();
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             new ChromePageInfo(
-                    activity.getModalDialogManagerSupplier(), null, OpenedFromSource.TOOLBAR)
+                    activity.getModalDialogManagerSupplier(), null, OpenedFromSource.TOOLBAR, null)
                     .show(tab, PageInfoController.NO_HIGHLIGHTED_PERMISSION);
         });
         onViewWaiting(allOf(withId(R.id.page_info_url_wrapper), isDisplayed()));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
index f570bd0..cdf5d93 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/page_info/PageInfoViewTest.java
@@ -207,7 +207,7 @@
         Tab tab = activity.getActivityTab();
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             new ChromePageInfo(activity.getModalDialogManagerSupplier(), null,
-                    PageInfoController.OpenedFromSource.TOOLBAR)
+                    PageInfoController.OpenedFromSource.TOOLBAR, null)
                     .show(tab, highlightedPermission);
         });
         onViewWaiting(allOf(withId(R.id.page_info_url_wrapper), isDisplayed()));
@@ -614,7 +614,7 @@
             ChromePageInfoControllerDelegate pageInfoControllerDelegate =
                     new ChromePageInfoControllerDelegate(activity, tab.getWebContents(),
                             activity::getModalDialogManager,
-                            new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab)) {
+                            new OfflinePageUtils.TabOfflinePageLoadUrlDelegate(tab), null) {
                         @Override
                         public boolean isShowingPaintPreviewPage() {
                             return true;
diff --git a/chrome/android/trichrome.gni b/chrome/android/trichrome.gni
index d0de691..5a97c2f5 100644
--- a/chrome/android/trichrome.gni
+++ b/chrome/android/trichrome.gni
@@ -35,6 +35,7 @@
   "trichrome_library=$trichrome_library_package",
   "trichrome_certdigest=$trichrome_certdigest",
   "use32bitAbi=android:use32bitAbi=\"true\"",
+  "zygote_preload_class=org.chromium.chrome.app.TrichromeZygotePreload",
 ]
 
 trichrome_synchronized_proguard =
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index bc7d2d69..aa439b1 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -4475,6 +4475,18 @@
   <message name="IDS_CROSTINI_UPGRADER_NOT_NOW" desc="Text on the button to defer performing the upgrade">
     Not now
   </message>
+  <message name="IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_TITLE" desc="Title for a dialog to warn the user that the OS version in their crostini container is unsupported">
+    Upgrade your Linux container
+  </message>
+  <message name="IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_BODY" desc="Body of a dialog to warn the user that the OS version in their crostini container is unsupported">
+    The operating system in your Linux container is no longer supported. It will stop receiving security updates and bug fixes, and features that currently work may break unexpectedly. Please upgrade to the latest version to continue using Linux.
+  </message>
+  <message name="IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_CONTINUE_BUTTON" desc="Button to continue using crostini even though the OS version in their crostini container is unsupported">
+    Continue anyway
+  </message>
+  <message name="IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_UPGRADE_BUTTON" desc="Button to begin upgrading the crostini container after warning that the OS version in their crostini container is unsupported">
+    Upgrade
+  </message>
   <message name="IDS_CROSTINI_ANSIBLE_SOFTWARE_CONFIG_LABEL" desc="Label for dialog warning user of unavailable Linux container until software configurations are applied.">
     Configuring Linux
   </message>
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_BODY.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_BODY.png.sha1
new file mode 100644
index 0000000..bb779fd
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_BODY.png.sha1
@@ -0,0 +1 @@
+01eeff59251c430b653b9bc2c3d445997beb330e
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_CONTINUE_BUTTON.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_CONTINUE_BUTTON.png.sha1
new file mode 100644
index 0000000..bb779fd
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_CONTINUE_BUTTON.png.sha1
@@ -0,0 +1 @@
+01eeff59251c430b653b9bc2c3d445997beb330e
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_TITLE.png.sha1
new file mode 100644
index 0000000..bb779fd
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_TITLE.png.sha1
@@ -0,0 +1 @@
+01eeff59251c430b653b9bc2c3d445997beb330e
\ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_UPGRADE_BUTTON.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_UPGRADE_BUTTON.png.sha1
new file mode 100644
index 0000000..bb779fd
--- /dev/null
+++ b/chrome/app/chromeos_strings_grdp/IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_UPGRADE_BUTTON.png.sha1
@@ -0,0 +1 @@
+01eeff59251c430b653b9bc2c3d445997beb330e
\ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 00f2896..4363a70 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -7327,6 +7327,22 @@
         </if>
       </if>
 
+      <!-- Side Search -->
+      <if expr="enable_side_search">
+        <message name="IDS_ACCNAME_SIDE_SEARCH_TOOLBAR_BUTTON" desc="The accessible name for the side search toolbar button">
+          Toggle side search
+        </message>
+        <message name="IDS_ACCNAME_SIDE_SEARCH_CLOSE_BUTTON" desc="The accessible name for the side search header close button">
+          Close side search
+        </message>
+        <message name="IDS_TOOLTIP_SIDE_SEARCH_TOOLBAR_BUTTON" desc="The tooltip for the side search toolbar button">
+          Toggle side search
+        </message>
+        <message name="IDS_TOOLTIP_SIDE_SEARCH_CLOSE_BUTTON" desc="The tooltip for the side search header close button">
+          Close side search
+        </message>
+      </if>
+
       <!-- Tab Search -->
       <message name="IDS_TAB_SEARCH_PROMO" desc="Promo UI shown next to the tab search button to encourage it's use.">
         To search your tabs, click here
diff --git a/chrome/app/generated_resources_grd/IDS_ACCNAME_SIDE_SEARCH_CLOSE_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_ACCNAME_SIDE_SEARCH_CLOSE_BUTTON.png.sha1
new file mode 100644
index 0000000..a93fe802
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_ACCNAME_SIDE_SEARCH_CLOSE_BUTTON.png.sha1
@@ -0,0 +1 @@
+30e267d70147ff7aa124da94726639e50f03b371
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_ACCNAME_SIDE_SEARCH_TOOLBAR_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_ACCNAME_SIDE_SEARCH_TOOLBAR_BUTTON.png.sha1
new file mode 100644
index 0000000..e71b5f8
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_ACCNAME_SIDE_SEARCH_TOOLBAR_BUTTON.png.sha1
@@ -0,0 +1 @@
+bdec194d1ae73569006e4d12c6a14a812bd9c60f
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TOOLTIP_SIDE_SEARCH_CLOSE_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_TOOLTIP_SIDE_SEARCH_CLOSE_BUTTON.png.sha1
new file mode 100644
index 0000000..a93fe802
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TOOLTIP_SIDE_SEARCH_CLOSE_BUTTON.png.sha1
@@ -0,0 +1 @@
+30e267d70147ff7aa124da94726639e50f03b371
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_TOOLTIP_SIDE_SEARCH_TOOLBAR_BUTTON.png.sha1 b/chrome/app/generated_resources_grd/IDS_TOOLTIP_SIDE_SEARCH_TOOLBAR_BUTTON.png.sha1
new file mode 100644
index 0000000..e71b5f8
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_TOOLTIP_SIDE_SEARCH_TOOLBAR_BUTTON.png.sha1
@@ -0,0 +1 @@
+bdec194d1ae73569006e4d12c6a14a812bd9c60f
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 9f99e01..ea33294 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -1044,6 +1044,8 @@
     "password_manager/bulk_leak_check_service_factory.h",
     "password_manager/chrome_password_manager_client.cc",
     "password_manager/chrome_password_manager_client.h",
+    "password_manager/chrome_webauthn_credentials_delegate.cc",
+    "password_manager/chrome_webauthn_credentials_delegate.h",
     "password_manager/credentials_cleaner_runner_factory.cc",
     "password_manager/credentials_cleaner_runner_factory.h",
     "password_manager/field_info_manager_factory.cc",
@@ -2738,7 +2740,6 @@
       "android/favicon_helper.h",
       "android/feature_engagement/tracker_factory_android.cc",
       "android/feed/feed_process_scope_dependency_provider.cc",
-      "android/feed/feed_surface_scope_dependency_provider.cc",
       "android/feed/v2/background_refresh_task.cc",
       "android/feed/v2/background_refresh_task.h",
       "android/feed/v2/feed_image_fetch_client.cc",
@@ -4989,10 +4990,10 @@
       "lacros/metrics_reporting_observer.cc",
       "lacros/metrics_reporting_observer.h",
       "lacros/net/network_settings_translation.h",
-      "lacros/net/proxy_config_service_lacros.cc",
-      "lacros/net/proxy_config_service_lacros.h",
       "lacros/net/network_settings_translation_crosapi.cc",
       "lacros/net/network_settings_translation_net_proxy.cc",
+      "lacros/net/proxy_config_service_lacros.cc",
+      "lacros/net/proxy_config_service_lacros.h",
       "lacros/prefs_ash_observer.cc",
       "lacros/prefs_ash_observer.h",
       "lacros/snap_controller_lacros.cc",
@@ -5688,8 +5689,7 @@
     ]
   }
 
-  if ((is_win || is_linux || is_chromeos) && is_chrome_branded) {
-    # TODO(crbug/1229334): Add Mac support for Lens Region Search feature.
+  if (!is_android && is_chrome_branded) {
     deps += [ "//chrome/browser/lens/region_search" ]
   }
 
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index ff0942a..b8a91c01 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4261,6 +4261,10 @@
     {"arc-rt-vcpu-quad-core", flag_descriptions::kArcRtVcpuQuadCoreName,
      flag_descriptions::kArcRtVcpuQuadCoreDesc, kOsCrOS,
      FEATURE_VALUE_TYPE(arc::kRtVcpuQuadCore)},
+    {"arc-usb-device-attach-to-vm-experiment",
+     flag_descriptions::kArcUsbDeviceDefaultAttachToVmName,
+     flag_descriptions::kArcUsbDeviceDefaultAttachToVmDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(arc::kUsbDeviceDefaultAttachToArcVm)},
     {kArcUseHighMemoryDalvikProfileInternalName,
      flag_descriptions::kArcUseHighMemoryDalvikProfileName,
      flag_descriptions::kArcUseHighMemoryDalvikProfileDesc, kOsCrOS,
diff --git a/chrome/browser/android/compositor/scene_layer/toolbar_swipe_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/toolbar_swipe_scene_layer.cc
index cdc68f7..cd55113c 100644
--- a/chrome/browser/android/compositor/scene_layer/toolbar_swipe_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/toolbar_swipe_scene_layer.cc
@@ -34,14 +34,20 @@
     jfloat x,
     jfloat y) {
   background_color_ = default_background_color;
-
   ContentLayer* content_layer =
       left_tab ? left_content_layer_.get() : right_content_layer_.get();
   if (!content_layer)
     return;
 
-  content_layer->SetProperties(id, can_use_live_layer, 1.0f, false, 1.0f, 1.0f,
-                               false, gfx::Rect());
+  // Update layer visibility based on whether there is a valid tab ID.
+  content_layer->layer()->SetHideLayerAndSubtree(id < 0);
+
+  if (id < 0)
+    return;
+
+  content_layer->SetProperties(id, can_use_live_layer,
+                               can_use_live_layer ? 0.0f : 1.0f, false, 1.0f,
+                               1.0f, false, gfx::Rect());
   content_layer->layer()->SetPosition(gfx::PointF(x, y));
 }
 
diff --git a/chrome/browser/android/feed/feed_surface_scope_dependency_provider.cc b/chrome/browser/android/feed/feed_surface_scope_dependency_provider.cc
deleted file mode 100644
index 4c82d6ed..0000000
--- a/chrome/browser/android/feed/feed_surface_scope_dependency_provider.cc
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2020 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/android/jni_android.h"
-#include "base/android/jni_array.h"
-#include "base/android/jni_string.h"
-#include "chrome/android/chrome_jni_headers/FeedSurfaceScopeDependencyProvider_jni.h"
-#include "chrome/browser/android/feed/v2/feed_service_factory.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/profiles/profile_manager.h"
-#include "components/feed/core/v2/public/feed_api.h"
-#include "components/feed/core/v2/public/feed_service.h"
-#include "components/feed/core/v2/public/feed_stream_surface.h"
-#include "components/variations/variations_ids_provider.h"
-
-namespace feed {
-namespace android {
-
-static FeedApi* GetFeedApi() {
-  FeedService* service = FeedServiceFactory::GetForBrowserContext(
-      ProfileManager::GetLastUsedProfile());
-  if (!service)
-    return nullptr;
-  return service->GetStream();
-}
-
-static void JNI_FeedSurfaceScopeDependencyProvider_ProcessViewAction(
-    JNIEnv* env,
-    const base::android::JavaParamRef<jbyteArray>& data) {
-  FeedApi* feed_stream_api = GetFeedApi();
-  if (!feed_stream_api)
-    return;
-  std::string data_string;
-  base::android::JavaByteArrayToString(env, data, &data_string);
-  feed_stream_api->ProcessViewAction(data_string);
-}
-
-static base::android::ScopedJavaLocalRef<jstring>
-JNI_FeedSurfaceScopeDependencyProvider_GetSessionId(JNIEnv* env) {
-  std::string session;
-  FeedApi* feed_stream_api = GetFeedApi();
-  if (feed_stream_api) {
-    session = feed_stream_api->GetSessionId();
-  }
-
-  return base::android::ConvertUTF8ToJavaString(env, session);
-}
-
-static base::android::ScopedJavaLocalRef<jintArray>
-JNI_FeedSurfaceScopeDependencyProvider_GetExperimentIds(JNIEnv* env) {
-  auto* variations_ids_provider =
-      variations::VariationsIdsProvider::GetInstance();
-  DCHECK(variations_ids_provider != nullptr);
-
-  return base::android::ToJavaIntArray(
-      env, variations_ids_provider->GetVariationsVectorForWebPropertiesKeys());
-}
-
-}  // namespace android
-}  // namespace feed
diff --git a/chrome/browser/apps/app_service/intent_util.cc b/chrome/browser/apps/app_service/intent_util.cc
index 6f441c47..e7d447e 100644
--- a/chrome/browser/apps/app_service/intent_util.cc
+++ b/chrome/browser/apps/app_service/intent_util.cc
@@ -498,9 +498,12 @@
     const arc::IntentFilter& arc_intent_filter) {
   auto intent_filter = apps::mojom::IntentFilter::New();
 
+  bool has_view_action = false;
+
   std::vector<apps::mojom::ConditionValuePtr> action_condition_values;
   for (auto& arc_action : arc_intent_filter.actions()) {
     const char* action = ConvertArcToAppServiceIntentAction(arc_action);
+    has_view_action = has_view_action || action == kIntentActionView;
 
     if (!action) {
       continue;
@@ -556,6 +559,16 @@
     path_condition_values.push_back(
         apps_util::MakeConditionValue(path.pattern(), match_type));
   }
+
+  // For ARC apps, specifying a path is optional. For any intent filters which
+  // match every URL on a host with a "view" action, add a path which matches
+  // everything to ensure the filter is treated as a supported link.
+  if (path_condition_values.empty() && has_view_action &&
+      arc_intent_filter.authorities().size() > 0 &&
+      arc_intent_filter.schemes().size() > 0) {
+    path_condition_values.push_back(apps_util::MakeConditionValue(
+        "/", apps::mojom::PatternMatchType::kPrefix));
+  }
   if (!path_condition_values.empty()) {
     auto path_condition = apps_util::MakeCondition(
         apps::mojom::ConditionType::kPattern, std::move(path_condition_values));
diff --git a/chrome/browser/apps/app_service/intent_util_unittest.cc b/chrome/browser/apps/app_service/intent_util_unittest.cc
index acf0359..80d3add 100644
--- a/chrome/browser/apps/app_service/intent_util_unittest.cc
+++ b/chrome/browser/apps/app_service/intent_util_unittest.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/web_applications/test/web_app_test_utils.h"
 #include "chrome/common/chrome_features.h"
 #include "components/arc/intent_helper/intent_constants.h"
+#include "components/arc/intent_helper/intent_filter.h"
 #include "components/arc/mojom/intent_helper.mojom.h"
 #include "components/services/app_service/public/cpp/intent_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -334,3 +335,35 @@
             apps_util::CreateLaunchIntent("com.android.vending",
                                           intent_with_text_and_title));
 }
+
+// Converting an Arc Intent filter for a URL view intent filter should add a
+// condition covering every possible path.
+TEST_F(IntentUtilsTest, ConvertArcIntentFilter_AddsMissingPath) {
+  const char* kPackageName = "com.foo.bar";
+  const char* kHost = "www.google.com";
+  const char* kPath = "/";
+  const char* kScheme = "https";
+
+  std::vector<arc::IntentFilter::AuthorityEntry> authorities1;
+  authorities1.emplace_back(kHost, 0);
+  std::vector<arc::IntentFilter::PatternMatcher> patterns;
+  patterns.emplace_back(kPath, arc::mojom::PatternType::PATTERN_PREFIX);
+
+  arc::IntentFilter filter_with_path(kPackageName, {arc::kIntentActionView},
+                                     std::move(authorities1),
+                                     std::move(patterns), {kScheme}, {});
+
+  IntentFilterPtr app_service_filter1 =
+      apps_util::ConvertArcToAppServiceIntentFilter(filter_with_path);
+
+  std::vector<arc::IntentFilter::AuthorityEntry> authorities2;
+  authorities2.emplace_back(kHost, 0);
+  arc::IntentFilter filter_without_path(kPackageName, {arc::kIntentActionView},
+                                        std::move(authorities2), {}, {kScheme},
+                                        {});
+
+  IntentFilterPtr app_service_filter2 =
+      apps_util::ConvertArcToAppServiceIntentFilter(filter_without_path);
+
+  ASSERT_EQ(app_service_filter1, app_service_filter2);
+}
diff --git a/chrome/browser/ash/crostini/DEPS b/chrome/browser/ash/crostini/DEPS
new file mode 100644
index 0000000..666a0dd
--- /dev/null
+++ b/chrome/browser/ash/crostini/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+chrome/browser/ui/views/crostini"
+]
\ No newline at end of file
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc
index 2e1eaa2..9046f813 100644
--- a/chrome/browser/ash/crostini/crostini_manager.cc
+++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -51,6 +51,7 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/views/crostini/crostini_expired_container_warning_view.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/pref_names.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -3159,16 +3160,33 @@
                                     CrostiniResult result) {
   auto range = restarters_by_container_.equal_range(restarter->container_id());
   std::vector<std::unique_ptr<CrostiniRestarter>> pending_restarters;
-  // Erase first, because restarter->RunCallback() may modify our maps.
+
+  // Erase first, because restarter->RunCallback() may modify our maps, and
+  // because the upgrade process will want to run more restarters.
   for (auto it = range.first; it != range.second; ++it) {
     CrostiniManager::RestartId restart_id = it->second;
     pending_restarters.emplace_back(std::move(restarters_by_id_[restart_id]));
     restarters_by_id_.erase(restart_id);
   }
   restarters_by_container_.erase(range.first, range.second);
-  for (const auto& pending_restarter : pending_restarters) {
-    pending_restarter->result_ = result;
-    pending_restarter->RunCallback(result);
+
+  std::vector<base::OnceClosure> callbacks;
+  for (auto&& restarter : pending_restarters) {
+    callbacks.push_back(base::BindOnce(
+        [](std::unique_ptr<CrostiniRestarter> restarter,
+           CrostiniResult result) {
+          restarter->result_ = result;
+          restarter->RunCallback(result);
+        },
+        std::move(restarter), result));
+  }
+
+  if (ShouldWarnAboutExpiredVersion(profile_, restarter->container_id())) {
+    CrostiniExpiredContainerWarningView::Show(profile_, std::move(callbacks));
+  } else {
+    for (auto&& callback : callbacks) {
+      std::move(callback).Run();
+    }
   }
 }
 
@@ -3431,11 +3449,13 @@
     case vm_tools::cicerone::UpgradeContainerResponse::UNKNOWN:
     case vm_tools::cicerone::UpgradeContainerResponse::FAILED:
     default:
-      LOG(ERROR) << "Upgrade container failed. Failure reason "
-                 << response->failure_reason();
       result = CrostiniResult::UPGRADE_CONTAINER_FAILED;
       break;
   }
+  if (!response->failure_reason().empty()) {
+    LOG(ERROR) << "Upgrade container failed. Failure reason: "
+               << response->failure_reason();
+  }
   std::move(callback).Run(result);
 }
 
diff --git a/chrome/browser/ash/crostini/crostini_util.cc b/chrome/browser/ash/crostini/crostini_util.cc
index 7cf25ba3..4addcba9 100644
--- a/chrome/browser/ash/crostini/crostini_util.cc
+++ b/chrome/browser/ash/crostini/crostini_util.cc
@@ -41,7 +41,9 @@
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_window.h"
 #include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h"
+#include "chrome/browser/ui/webui/chromeos/system_web_dialog_delegate.h"
 #include "chrome/common/chrome_features.h"
+#include "chrome/common/webui_url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/prefs/pref_service.h"
 #include "components/user_manager/user.h"
@@ -523,6 +525,35 @@
   }
 }
 
+bool IsContainerVersionExpired(Profile* profile,
+                               const ContainerId& container_id) {
+  auto* value = GetContainerPrefValue(profile, container_id,
+                                      prefs::kContainerOsVersionKey);
+  if (!value)
+    return false;
+
+  auto version = static_cast<ContainerOsVersion>(value->GetInt());
+  return version == ContainerOsVersion::kDebianStretch;
+}
+
+bool ShouldWarnAboutExpiredVersion(Profile* profile,
+                                   const ContainerId& container_id) {
+  if (!CrostiniFeatures::Get()->IsContainerUpgradeUIAllowed(profile)) {
+    return false;
+  }
+  if (container_id != ContainerId::GetDefault()) {
+    return false;
+  }
+  // If the warning dialog is already open we can add more callbacks to it, but
+  // if we've moved to the upgrade dialog proper we should run them now as they
+  // may be part of the upgrade process.
+  if (chromeos::SystemWebDialogDelegate::FindInstance(
+          GURL{chrome::kChromeUICrostiniUpgraderUrl}.spec())) {
+    return false;
+  }
+  return IsContainerVersionExpired(profile, container_id);
+}
+
 std::u16string GetTimeRemainingMessage(base::TimeTicks start, int percent) {
   // Only estimate once we've spent at least 3 seconds OR gotten 10% of the way
   // through.
diff --git a/chrome/browser/ash/crostini/crostini_util.h b/chrome/browser/ash/crostini/crostini_util.h
index 4e68abcc..675cec75 100644
--- a/chrome/browser/ash/crostini/crostini_util.h
+++ b/chrome/browser/ash/crostini/crostini_util.h
@@ -212,6 +212,12 @@
                          const std::string& key,
                          base::Value value);
 
+bool IsContainerVersionExpired(Profile* profile,
+                               const ContainerId& container_id);
+
+bool ShouldWarnAboutExpiredVersion(Profile* profile,
+                                   const ContainerId& container_id);
+
 const ContainerId& DefaultContainerId();
 
 bool IsCrostiniWindow(const aura::Window* window);
diff --git a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.cc b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.cc
index d4e646ac..cf695d7 100644
--- a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.cc
+++ b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.cc
@@ -157,7 +157,7 @@
       dlp_rules_manager_, data_src, data_dst, size, &src_pattern, &dst_pattern);
 
   ReportEvent(data_src, data_dst, src_pattern, dst_pattern, level,
-              /*is_clipboard_event*/ true);
+              /*is_clipboard_event=*/true);
 
   bool notify_on_paste = ShouldNotifyOnPaste(data_dst);
 
@@ -245,30 +245,42 @@
   }
 }
 
-bool DataTransferDlpController::IsDragDropAllowed(
-    const ui::DataTransferEndpoint* const data_src,
-    const ui::DataTransferEndpoint* const data_dst,
-    const bool is_drop) {
+void DataTransferDlpController::DropIfAllowed(
+    const ui::DataTransferEndpoint* data_src,
+    const ui::DataTransferEndpoint* data_dst,
+    base::OnceClosure drop_cb) {
   std::string src_pattern;
   std::string dst_pattern;
   DlpRulesManager::Level level =
       IsDataTransferAllowed(dlp_rules_manager_, data_src, data_dst,
                             absl::nullopt, &src_pattern, &dst_pattern);
 
-  if (is_drop) {
-    ReportEvent(data_src, data_dst, src_pattern, dst_pattern, level,
-                /*is_clipboard_event*/ false);
-  }
+  ReportEvent(data_src, data_dst, src_pattern, dst_pattern, level,
+              /*is_clipboard_event*/ false);
 
-  if (level == DlpRulesManager::Level::kBlock && is_drop) {
-    SYSLOG(INFO) << "DLP blocked drop of dragged data";
-    NotifyBlockedDrop(data_src, data_dst);
+  switch (level) {
+    case DlpRulesManager::Level::kBlock:
+      SYSLOG(INFO) << "DLP blocked drop of dragged data";
+      NotifyBlockedDrop(data_src, data_dst);
+      break;
+
+    case DlpRulesManager::Level::kWarn:
+      WarnOnDrop(data_src, data_dst, std::move(drop_cb));
+      break;
+
+    case DlpRulesManager::Level::kAllow:
+      FALLTHROUGH;
+    case DlpRulesManager::Level::kReport:
+      std::move(drop_cb).Run();
+      break;
+
+    case DlpRulesManager::Level::kNotSet:
+      NOTREACHED();
   }
 
   const bool is_drop_allowed = (level == DlpRulesManager::Level::kAllow) ||
                                (level == DlpRulesManager::Level::kReport);
   DlpBooleanHistogram(dlp::kDragDropBlockedUMA, !is_drop_allowed);
-  return is_drop_allowed;
 }
 
 DataTransferDlpController::DataTransferDlpController(
@@ -315,6 +327,13 @@
   drag_drop_notifier_.NotifyBlockedAction(data_src, data_dst);
 }
 
+void DataTransferDlpController::WarnOnDrop(
+    const ui::DataTransferEndpoint* const data_src,
+    const ui::DataTransferEndpoint* const data_dst,
+    base::OnceClosure drop_cb) {
+  drag_drop_notifier_.WarnOnDrop(data_src, data_dst, std::move(drop_cb));
+}
+
 bool DataTransferDlpController::ShouldSkipReporting(
     const ui::DataTransferEndpoint* const data_src,
     const ui::DataTransferEndpoint* const data_dst,
diff --git a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.h b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.h
index fe99a4fc..6e2702c 100644
--- a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.h
+++ b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller.h
@@ -43,9 +43,9 @@
                       const absl::optional<size_t> size,
                       content::RenderFrameHost* rfh,
                       base::OnceCallback<void(bool)> callback) override;
-  bool IsDragDropAllowed(const ui::DataTransferEndpoint* const data_src,
-                         const ui::DataTransferEndpoint* const data_dst,
-                         const bool is_drop) override;
+  void DropIfAllowed(const ui::DataTransferEndpoint* data_src,
+                     const ui::DataTransferEndpoint* data_dst,
+                     base::OnceClosure drop_cb) override;
 
  protected:
   explicit DataTransferDlpController(const DlpRulesManager& dlp_rules_manager);
@@ -74,6 +74,10 @@
       const ui::DataTransferEndpoint* const data_src,
       const ui::DataTransferEndpoint* const data_dst);
 
+  virtual void WarnOnDrop(const ui::DataTransferEndpoint* const data_src,
+                          const ui::DataTransferEndpoint* const data_dst,
+                          base::OnceClosure drop_cb);
+
   bool ShouldSkipReporting(const ui::DataTransferEndpoint* const data_src,
                            const ui::DataTransferEndpoint* const data_dst,
                            base::TimeTicks curr_time);
diff --git a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_unittest.cc b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_unittest.cc
index f380c11..764f8f881 100644
--- a/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_unittest.cc
+++ b/chrome/browser/ash/policy/dlp/data_transfer_dlp_controller_unittest.cc
@@ -65,6 +65,11 @@
 
   MOCK_METHOD1(ShouldCancelOnWarn,
                bool(const ui::DataTransferEndpoint* const data_dst));
+
+  MOCK_METHOD3(WarnOnDrop,
+               void(const ui::DataTransferEndpoint* const data_src,
+                    const ui::DataTransferEndpoint* const data_dst,
+                    base::OnceClosure drop_cb));
 };
 
 // Creates a new MockDlpRulesManager for the given |context|.
@@ -129,8 +134,12 @@
 TEST_F(DataTransferDlpControllerTest, NullSrc) {
   EXPECT_EQ(true, dlp_controller_.IsClipboardReadAllowed(nullptr, nullptr,
                                                          absl::nullopt));
-  EXPECT_EQ(true, dlp_controller_.IsDragDropAllowed(nullptr, nullptr,
-                                                    /*is_drop=*/false));
+
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  EXPECT_CALL(callback, Run());
+
+  dlp_controller_.DropIfAllowed(nullptr, nullptr, callback.Get());
+
   histogram_tester_.ExpectUniqueSample(
       GetDlpHistogramPrefix() + dlp::kClipboardReadBlockedUMA, false, 1);
   histogram_tester_.ExpectUniqueSample(
@@ -287,13 +296,15 @@
                                                          absl::nullopt));
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
-  // IsDragDropAllowed
+  // DropIfAllowed
   EXPECT_CALL(rules_manager_, IsRestrictedDestination)
       .WillOnce(testing::Return(DlpRulesManager::Level::kAllow));
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  EXPECT_CALL(callback, Run());
 
-  EXPECT_EQ(true, dlp_controller_.IsDragDropAllowed(&data_src_, dst_ptr_,
-                                                    /*is_drop=*/do_notify_));
+  dlp_controller_.DropIfAllowed(&data_src_, dst_ptr_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
+
   histogram_tester_.ExpectUniqueSample(
       GetDlpHistogramPrefix() + dlp::kClipboardReadBlockedUMA, false, 1);
   histogram_tester_.ExpectUniqueSample(
@@ -324,25 +335,19 @@
       GetDlpHistogramPrefix() + dlp::kClipboardReadBlockedUMA, true, 1);
 }
 
-TEST_P(DlpControllerTest, Block_IsDragDropAllowed) {
+TEST_P(DlpControllerTest, Block_DropIfAllowed) {
   EXPECT_CALL(rules_manager_, IsRestrictedDestination)
       .WillOnce(testing::Return(DlpRulesManager::Level::kBlock));
-  if (do_notify_)
-    EXPECT_CALL(dlp_controller_, NotifyBlockedDrop);
+  EXPECT_CALL(dlp_controller_, NotifyBlockedDrop);
+  ::testing::StrictMock<base::MockOnceClosure> callback;
 
-  EXPECT_EQ(false, dlp_controller_.IsDragDropAllowed(&data_src_, dst_ptr_,
-                                                     /*is_drop=*/do_notify_));
+  dlp_controller_.DropIfAllowed(&data_src_, dst_ptr_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
-  if (do_notify_) {
-    EXPECT_EQ(events_.size(), 1u);
-    EXPECT_THAT(events_[0],
-                IsDlpPolicyEvent(CreateDlpPolicyEvent(
-                    "", "", DlpRulesManager::Restriction::kClipboard,
-                    DlpRulesManager::Level::kBlock)));
-  } else {
-    EXPECT_TRUE(events_.empty());
-  }
+  EXPECT_EQ(events_.size(), 1u);
+  EXPECT_THAT(events_[0], IsDlpPolicyEvent(CreateDlpPolicyEvent(
+                              "", "", DlpRulesManager::Restriction::kClipboard,
+                              DlpRulesManager::Level::kBlock)));
 
   histogram_tester_.ExpectUniqueSample(
       GetDlpHistogramPrefix() + dlp::kDragDropBlockedUMA, true, 1);
@@ -367,26 +372,22 @@
   }
 }
 
-TEST_P(DlpControllerTest, Report_IsDragDropAllowed) {
+TEST_P(DlpControllerTest, Report_DropIfAllowed) {
   EXPECT_CALL(rules_manager_, IsRestrictedDestination)
       .WillOnce(testing::Return(DlpRulesManager::Level::kReport));
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  EXPECT_CALL(callback, Run());
 
-  EXPECT_EQ(true, dlp_controller_.IsDragDropAllowed(&data_src_, dst_ptr_,
-                                                    /*is_drop=*/do_notify_));
+  dlp_controller_.DropIfAllowed(&data_src_, dst_ptr_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
-  if (do_notify_) {
-    EXPECT_EQ(events_.size(), 1u);
-    EXPECT_THAT(events_[0],
-                IsDlpPolicyEvent(CreateDlpPolicyEvent(
-                    "", "", DlpRulesManager::Restriction::kClipboard,
-                    DlpRulesManager::Level::kReport)));
-  } else {
-    EXPECT_TRUE(events_.empty());
-  }
+  EXPECT_EQ(events_.size(), 1u);
+  EXPECT_THAT(events_[0], IsDlpPolicyEvent(CreateDlpPolicyEvent(
+                              "", "", DlpRulesManager::Restriction::kClipboard,
+                              DlpRulesManager::Level::kReport)));
 }
 
-TEST_P(DlpControllerTest, Warn) {
+TEST_P(DlpControllerTest, Warn_IsClipboardReadAllowed) {
   // ShouldPasteOnWarn returns false.
   EXPECT_CALL(rules_manager_, IsRestrictedDestination)
       .WillOnce(testing::Return(DlpRulesManager::Level::kWarn));
@@ -433,6 +434,20 @@
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 }
 
+TEST_P(DlpControllerTest, Warn_DropIfAllowed) {
+  EXPECT_CALL(rules_manager_, IsRestrictedDestination)
+      .WillOnce(testing::Return(DlpRulesManager::Level::kWarn));
+  EXPECT_CALL(dlp_controller_, WarnOnDrop);
+
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+
+  dlp_controller_.DropIfAllowed(&data_src_, dst_ptr_, callback.Get());
+  testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
+
+  histogram_tester_.ExpectUniqueSample(
+      GetDlpHistogramPrefix() + dlp::kDragDropBlockedUMA, true, 1);
+}
+
 // Create a version of the test class for parameterized testing.
 class DlpControllerVMsTest : public DataTransferDlpControllerTest {
  protected:
@@ -480,13 +495,15 @@
                                                          absl::nullopt));
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
-  // IsDragDropAllowed
+  // DropIfAllowed
   EXPECT_CALL(rules_manager_, IsRestrictedComponent)
       .WillOnce(testing::Return(DlpRulesManager::Level::kAllow));
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  EXPECT_CALL(callback, Run());
 
-  EXPECT_EQ(true, dlp_controller_.IsDragDropAllowed(&data_src, &data_dst,
-                                                    /*is_drop=*/do_notify));
+  dlp_controller_.DropIfAllowed(&data_src, &data_dst, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
+
   histogram_tester_.ExpectUniqueSample(
       GetDlpHistogramPrefix() + dlp::kClipboardReadBlockedUMA, false, 1);
   histogram_tester_.ExpectUniqueSample(
@@ -517,25 +534,20 @@
       GetDlpHistogramPrefix() + dlp::kClipboardReadBlockedUMA, true, 1);
 }
 
-TEST_P(DlpControllerVMsTest, Block_IsDragDropAllowed) {
+TEST_P(DlpControllerVMsTest, Block_DropIfAllowed) {
   EXPECT_CALL(rules_manager_, IsRestrictedComponent)
       .WillOnce(testing::Return(DlpRulesManager::Level::kBlock));
-  if (do_notify_)
-    EXPECT_CALL(dlp_controller_, NotifyBlockedDrop);
+  EXPECT_CALL(dlp_controller_, NotifyBlockedDrop);
+  ::testing::StrictMock<base::MockOnceClosure> callback;
 
-  EXPECT_EQ(false, dlp_controller_.IsDragDropAllowed(&data_src_, &data_dst_,
-                                                     /*is_drop=*/do_notify_));
+  dlp_controller_.DropIfAllowed(&data_src_, &data_dst_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
-  if (do_notify_) {
-    EXPECT_EQ(events_.size(), 1u);
-    EXPECT_THAT(events_[0], IsDlpPolicyEvent(CreateDlpPolicyEvent(
-                                "", GetComponent(endpoint_type_.value()),
-                                DlpRulesManager::Restriction::kClipboard,
-                                DlpRulesManager::Level::kBlock)));
-  } else {
-    EXPECT_TRUE(events_.empty());
-  }
+  ASSERT_EQ(events_.size(), 1u);
+  EXPECT_THAT(events_[0], IsDlpPolicyEvent(CreateDlpPolicyEvent(
+                              "", GetComponent(endpoint_type_.value()),
+                              DlpRulesManager::Restriction::kClipboard,
+                              DlpRulesManager::Level::kBlock)));
 
   histogram_tester_.ExpectUniqueSample(
       GetDlpHistogramPrefix() + dlp::kDragDropBlockedUMA, true, 1);
@@ -560,26 +572,23 @@
   }
 }
 
-TEST_P(DlpControllerVMsTest, Report_IsDragDropAllowed) {
+TEST_P(DlpControllerVMsTest, Report_DropIfAllowed) {
   EXPECT_CALL(rules_manager_, IsRestrictedComponent)
       .WillOnce(testing::Return(DlpRulesManager::Level::kReport));
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  EXPECT_CALL(callback, Run());
 
-  EXPECT_EQ(true, dlp_controller_.IsDragDropAllowed(&data_src_, &data_dst_,
-                                                    /*is_drop=*/do_notify_));
+  dlp_controller_.DropIfAllowed(&data_src_, &data_dst_, callback.Get());
   testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
 
-  if (do_notify_) {
-    EXPECT_EQ(events_.size(), 1u);
-    EXPECT_THAT(events_[0], IsDlpPolicyEvent(CreateDlpPolicyEvent(
-                                "", GetComponent(endpoint_type_.value()),
-                                DlpRulesManager::Restriction::kClipboard,
-                                DlpRulesManager::Level::kReport)));
-  } else {
-    EXPECT_TRUE(events_.empty());
-  }
+  ASSERT_EQ(events_.size(), 1u);
+  EXPECT_THAT(events_[0], IsDlpPolicyEvent(CreateDlpPolicyEvent(
+                              "", GetComponent(endpoint_type_.value()),
+                              DlpRulesManager::Restriction::kClipboard,
+                              DlpRulesManager::Level::kReport)));
 }
 
-TEST_P(DlpControllerVMsTest, Warn) {
+TEST_P(DlpControllerVMsTest, Warn_IsClipboardReadAllowed) {
   ui::DataTransferEndpoint data_src(url::Origin::Create(GURL(kExample1Url)));
   absl::optional<ui::EndpointType> endpoint_type;
   bool do_notify;
@@ -600,4 +609,17 @@
       GetDlpHistogramPrefix() + dlp::kClipboardReadBlockedUMA, false, 1);
 }
 
+TEST_P(DlpControllerVMsTest, Warn_DropIfAllowed) {
+  EXPECT_CALL(rules_manager_, IsRestrictedComponent)
+      .WillOnce(testing::Return(DlpRulesManager::Level::kWarn));
+  EXPECT_CALL(dlp_controller_, WarnOnDrop);
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+
+  dlp_controller_.DropIfAllowed(&data_src_, &data_dst_, callback.Get());
+
+  testing::Mock::VerifyAndClearExpectations(&dlp_controller_);
+  histogram_tester_.ExpectUniqueSample(
+      GetDlpHistogramPrefix() + dlp::kDragDropBlockedUMA, true, 1);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.cc b/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.cc
index 53514fee..4b174e8 100644
--- a/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.cc
@@ -5,7 +5,9 @@
 #include "chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.h"
 
 #include <memory>
+#include <utility>
 
+#include "base/bind.h"
 #include "base/notreached.h"
 #include "chrome/browser/ash/policy/dlp/clipboard_bubble.h"
 #include "chrome/browser/ash/policy/dlp/dlp_clipboard_bubble_constants.h"
@@ -29,4 +31,44 @@
   ShowBlockBubble(l10n_util::GetStringFUTF16(
       IDS_POLICY_DLP_CLIPBOARD_BLOCKED_ON_PASTE, host_name));
 }
+
+void DlpDragDropNotifier::WarnOnDrop(
+    const ui::DataTransferEndpoint* const data_src,
+    const ui::DataTransferEndpoint* const data_dst,
+    base::OnceClosure drop_cb) {
+  DCHECK(data_src);
+  DCHECK(data_src->origin());
+
+  CloseWidget(widget_.get(), views::Widget::ClosedReason::kUnspecified);
+
+  const std::u16string host_name =
+      base::UTF8ToUTF16(data_src->origin()->host());
+
+  drop_cb_ = std::move(drop_cb);
+  auto proceed_cb = base::BindRepeating(&DlpDragDropNotifier::ProceedPressed,
+                                        base::Unretained(this));
+  auto cancel_cb = base::BindRepeating(&DlpDragDropNotifier::CancelPressed,
+                                       base::Unretained(this));
+
+  ShowWarningBubble(l10n_util::GetStringFUTF16(
+                        IDS_POLICY_DLP_CLIPBOARD_WARN_ON_PASTE, host_name),
+                    std::move(proceed_cb), std::move(cancel_cb));
+}
+
+void DlpDragDropNotifier::ProceedPressed(views::Widget* widget) {
+  if (drop_cb_)
+    std::move(drop_cb_).Run();
+  CloseWidget(widget, views::Widget::ClosedReason::kAcceptButtonClicked);
+}
+
+void DlpDragDropNotifier::CancelPressed(views::Widget* widget) {
+  CloseWidget(widget, views::Widget::ClosedReason::kCancelButtonClicked);
+}
+
+void DlpDragDropNotifier::OnWidgetClosing(views::Widget* widget) {
+  drop_cb_.Reset();
+
+  DlpDataTransferNotifier::OnWidgetClosing(widget);
+}
+
 }  // namespace policy
diff --git a/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.h b/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.h
index c26ceda0..f3e5fcc 100644
--- a/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.h
+++ b/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_ASH_POLICY_DLP_DLP_DRAG_DROP_NOTIFIER_H_
 #define CHROME_BROWSER_ASH_POLICY_DLP_DLP_DRAG_DROP_NOTIFIER_H_
 
+#include "base/callback.h"
 #include "chrome/browser/ash/policy/dlp/dlp_data_transfer_notifier.h"
 
 namespace policy {
@@ -21,6 +22,24 @@
   void NotifyBlockedAction(
       const ui::DataTransferEndpoint* const data_src,
       const ui::DataTransferEndpoint* const data_dst) override;
+
+  // Warns the user that this drop action is not recommended.
+  void WarnOnDrop(const ui::DataTransferEndpoint* const data_src,
+                  const ui::DataTransferEndpoint* const data_dst,
+                  base::OnceClosure drop_cb);
+
+ protected:
+  // Added as protected so tests can refer to them.
+  void ProceedPressed(views::Widget* widget);
+
+  void CancelPressed(views::Widget* widget);
+
+  // views::WidgetObserver
+  void OnWidgetClosing(views::Widget* widget) override;
+
+ private:
+  // Drop callback.
+  base::OnceClosure drop_cb_;
 };
 
 }  // namespace policy
diff --git a/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier_unittest.cc b/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier_unittest.cc
index d4ecd5d..5b0b7e0 100644
--- a/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier_unittest.cc
+++ b/chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier_unittest.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/ash/policy/dlp/dlp_drag_drop_notifier.h"
 
 #include "base/stl_util.h"
+#include "base/test/mock_callback.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -32,6 +33,15 @@
 
   // DlpDataTransferNotifier:
   MOCK_METHOD1(ShowBlockBubble, void(const std::u16string& text));
+  MOCK_METHOD3(ShowWarningBubble,
+               void(const std::u16string& text,
+                    base::RepeatingCallback<void(views::Widget*)> proceed_cb,
+                    base::RepeatingCallback<void(views::Widget*)> cancel_cb));
+  MOCK_METHOD2(CloseWidget,
+               void(views::Widget* widget, views::Widget::ClosedReason reason));
+
+  using DlpDragDropNotifier::CancelPressed;
+  using DlpDragDropNotifier::ProceedPressed;
 };
 
 }  // namespace
@@ -59,6 +69,53 @@
   notifier.NotifyBlockedAction(&data_src, base::OptionalOrNullptr(data_dst));
 }
 
+TEST_P(DragDropBubbleTestWithParam, ProceedWarnOnDrop) {
+  ::testing::StrictMock<MockDlpDragDropNotifier> notifier;
+  ui::DataTransferEndpoint data_src(url::Origin::Create(GURL(kExampleUrl)));
+  absl::optional<ui::DataTransferEndpoint> data_dst;
+  auto param = GetParam();
+  if (param.has_value())
+    data_dst.emplace(CreateEndpoint(param.value()));
+
+  EXPECT_CALL(notifier, CloseWidget(testing::_,
+                                    views::Widget::ClosedReason::kUnspecified));
+  EXPECT_CALL(notifier, ShowWarningBubble);
+
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  notifier.WarnOnDrop(&data_src, base::OptionalOrNullptr(data_dst),
+                      callback.Get());
+
+  EXPECT_CALL(notifier,
+              CloseWidget(testing::_,
+                          views::Widget::ClosedReason::kAcceptButtonClicked));
+
+  EXPECT_CALL(callback, Run());
+  notifier.ProceedPressed(nullptr);
+}
+
+TEST_P(DragDropBubbleTestWithParam, CancelWarnOnDrop) {
+  ::testing::StrictMock<MockDlpDragDropNotifier> notifier;
+  ui::DataTransferEndpoint data_src(url::Origin::Create(GURL(kExampleUrl)));
+  absl::optional<ui::DataTransferEndpoint> data_dst;
+  auto param = GetParam();
+  if (param.has_value())
+    data_dst.emplace(CreateEndpoint(param.value()));
+
+  EXPECT_CALL(notifier, CloseWidget(testing::_,
+                                    views::Widget::ClosedReason::kUnspecified));
+  EXPECT_CALL(notifier, ShowWarningBubble);
+
+  ::testing::StrictMock<base::MockOnceClosure> callback;
+  notifier.WarnOnDrop(&data_src, base::OptionalOrNullptr(data_dst),
+                      callback.Get());
+
+  EXPECT_CALL(notifier,
+              CloseWidget(testing::_,
+                          views::Widget::ClosedReason::kCancelButtonClicked));
+
+  notifier.CancelPressed(nullptr);
+}
+
 INSTANTIATE_TEST_SUITE_P(DlpDragDropNotifierTest,
                          DragDropBubbleTestWithParam,
                          ::testing::Values(absl::nullopt,
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.cc b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
index ca0e77b..c3c35bb8 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.cc
@@ -1569,6 +1569,10 @@
       chromeos::kReportDeviceAudioStatus, callback);
   network_interfaces_subscription_ = cros_settings_->AddSettingsObserver(
       chromeos::kReportDeviceNetworkInterfaces, callback);
+  network_configuration_subscription_ = cros_settings_->AddSettingsObserver(
+      chromeos::kReportDeviceNetworkConfiguration, callback);
+  network_status_subscription_ = cros_settings_->AddSettingsObserver(
+      chromeos::kReportDeviceNetworkStatus, callback);
   users_subscription_ = cros_settings_->AddSettingsObserver(
       chromeos::kReportDeviceUsers, callback);
   session_status_subscription_ = cros_settings_->AddSettingsObserver(
@@ -1696,6 +1700,7 @@
 
   // Keep the default values in sync with DeviceReportingProto in
   // components/policy/proto/chrome_device_policy.proto.
+  // TODO(b/195030842): Refactor how reporting policy variables are set.
   if (!cros_settings_->GetBoolean(chromeos::kReportDeviceVersionInfo,
                                   &report_version_info_)) {
     report_version_info_ = true;
@@ -1716,9 +1721,13 @@
                                   &report_kiosk_session_status_)) {
     report_kiosk_session_status_ = true;
   }
-  if (!cros_settings_->GetBoolean(chromeos::kReportDeviceNetworkInterfaces,
-                                  &report_network_interfaces_)) {
-    report_network_interfaces_ = true;
+  if (!cros_settings_->GetBoolean(chromeos::kReportDeviceNetworkConfiguration,
+                                  &report_network_configuration_)) {
+    report_network_configuration_ = true;
+  }
+  if (!cros_settings_->GetBoolean(chromeos::kReportDeviceNetworkStatus,
+                                  &report_network_status_)) {
+    report_network_status_ = true;
   }
   if (!cros_settings_->GetBoolean(chromeos::kReportDeviceUsers,
                                   &report_users_)) {
@@ -2263,9 +2272,8 @@
   return true;
 }
 
-bool DeviceStatusCollector::GetNetworkInterfaces(
+bool DeviceStatusCollector::GetNetworkConfiguration(
     em::DeviceStatusReportRequest* status) {
-  // Maps shill device type strings to proto enum constants.
   static const struct {
     const char* type_string;
     em::NetworkInterface::NetworkDeviceType type_constant;
@@ -2284,27 +2292,6 @@
       },
   };
 
-  // Maps shill device connection status to proto enum constants.
-  static const struct {
-    const char* state_string;
-    em::NetworkState::ConnectionState state_constant;
-  } kConnectionStateMap[] = {
-      {shill::kStateIdle, em::NetworkState::IDLE},
-      {shill::kStateCarrier, em::NetworkState::CARRIER},
-      {shill::kStateAssociation, em::NetworkState::ASSOCIATION},
-      {shill::kStateConfiguration, em::NetworkState::CONFIGURATION},
-      {shill::kStateReady, em::NetworkState::READY},
-      {shill::kStatePortal, em::NetworkState::PORTAL},
-      {shill::kStateNoConnectivity, em::NetworkState::PORTAL},
-      {shill::kStateRedirectFound, em::NetworkState::PORTAL},
-      {shill::kStatePortalSuspected, em::NetworkState::PORTAL},
-      {shill::kStateOffline, em::NetworkState::OFFLINE},
-      {shill::kStateOnline, em::NetworkState::ONLINE},
-      {shill::kStateDisconnect, em::NetworkState::DISCONNECT},
-      {shill::kStateFailure, em::NetworkState::FAILURE},
-      {shill::kStateActivationFailure, em::NetworkState::ACTIVATION_FAILURE},
-  };
-
   chromeos::NetworkStateHandler::DeviceStateList device_list;
   chromeos::NetworkStateHandler* network_state_handler =
       chromeos::NetworkHandler::Get()->network_state_handler();
@@ -2338,6 +2325,36 @@
     anything_reported = true;
   }
 
+  return anything_reported;
+}
+
+bool DeviceStatusCollector::GetNetworkStatus(
+    em::DeviceStatusReportRequest* status) {
+  // Maps shill device connection status to proto enum constants.
+  static const struct {
+    const char* state_string;
+    em::NetworkState::ConnectionState state_constant;
+  } kConnectionStateMap[] = {
+      {shill::kStateIdle, em::NetworkState::IDLE},
+      {shill::kStateCarrier, em::NetworkState::CARRIER},
+      {shill::kStateAssociation, em::NetworkState::ASSOCIATION},
+      {shill::kStateConfiguration, em::NetworkState::CONFIGURATION},
+      {shill::kStateReady, em::NetworkState::READY},
+      {shill::kStatePortal, em::NetworkState::PORTAL},
+      {shill::kStateNoConnectivity, em::NetworkState::PORTAL},
+      {shill::kStateRedirectFound, em::NetworkState::PORTAL},
+      {shill::kStatePortalSuspected, em::NetworkState::PORTAL},
+      {shill::kStateOffline, em::NetworkState::OFFLINE},
+      {shill::kStateOnline, em::NetworkState::ONLINE},
+      {shill::kStateDisconnect, em::NetworkState::DISCONNECT},
+      {shill::kStateFailure, em::NetworkState::FAILURE},
+      {shill::kStateActivationFailure, em::NetworkState::ACTIVATION_FAILURE},
+  };
+
+  bool anything_reported = false;
+  chromeos::NetworkStateHandler* network_state_handler =
+      chromeos::NetworkHandler::Get()->network_state_handler();
+
   user_manager::UserManager* user_manager = user_manager::UserManager::Get();
   const user_manager::User* const primary_user = user_manager->GetPrimaryUser();
   // Don't write network state for unaffiliated users or when no user is signed
@@ -2647,8 +2664,11 @@
     }
   }
 
-  if (report_network_interfaces_)
-    anything_reported |= GetNetworkInterfaces(status);
+  if (report_network_configuration_)
+    anything_reported |= GetNetworkConfiguration(status);
+
+  if (report_network_status_)
+    anything_reported |= GetNetworkStatus(status);
 
   if (report_users_)
     anything_reported |= GetUsers(status);
@@ -2863,8 +2883,9 @@
   std::string user_email = GetUserForActivityReporting();
   return !user_email.empty() && !IsDeviceLocalAccountUser(user_email, NULL);
 }
+// TODO(b/192252043): Remove this once management ui has been refactored.
 bool DeviceStatusCollector::ShouldReportNetworkInterfaces() const {
-  return report_network_interfaces_;
+  return false;
 }
 bool DeviceStatusCollector::ShouldReportUsers() const {
   // For more details, see comment in
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector.h b/chrome/browser/ash/policy/status_collector/device_status_collector.h
index 4ff9c471..7582e8d 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector.h
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector.h
@@ -286,7 +286,9 @@
   bool GetVersionInfo(enterprise_management::DeviceStatusReportRequest* status);
   bool GetWriteProtectSwitch(
       enterprise_management::DeviceStatusReportRequest* status);
-  bool GetNetworkInterfaces(
+  bool GetNetworkConfiguration(
+      enterprise_management::DeviceStatusReportRequest* status);
+  bool GetNetworkStatus(
       enterprise_management::DeviceStatusReportRequest* status);
   bool GetUsers(enterprise_management::DeviceStatusReportRequest* status);
   bool GetMemoryInfo(enterprise_management::DeviceStatusReportRequest* status);
@@ -458,7 +460,8 @@
 
   // Cached values of the reporting settings. These are enterprise only. There
   // are common ones in StatusCollector interface.
-  bool report_network_interfaces_ = false;
+  bool report_network_configuration_ = false;
+  bool report_network_status_ = false;
   bool report_users_ = false;
   bool report_kiosk_session_status_ = false;
   bool report_os_update_status_ = false;
@@ -483,7 +486,9 @@
 
   base::CallbackListSubscription activity_times_subscription_;
   base::CallbackListSubscription audio_status_subscription_;
+  base::CallbackListSubscription network_configuration_subscription_;
   base::CallbackListSubscription network_interfaces_subscription_;
+  base::CallbackListSubscription network_status_subscription_;
   base::CallbackListSubscription users_subscription_;
   base::CallbackListSubscription session_status_subscription_;
   base::CallbackListSubscription os_update_status_subscription_;
diff --git a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
index b3cf0a4..1ced7a22 100644
--- a/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/device_status_collector_browsertest.cc
@@ -194,6 +194,7 @@
     cros_healthd::CpuArchitectureEnum::kX86_64;
 constexpr em::CpuInfo::Architecture kFakeProtoArchitecture =
     em::CpuInfo::X86_64;
+constexpr bool kFakeKeylockerConfigurationState = false;
 constexpr uint32_t kFakeMaxClockSpeed = 3400000;
 constexpr uint32_t kFakeScalingMaxFrequency = 2700000;
 constexpr uint32_t kFakeScalingCurFrequency = 2400000;
@@ -613,10 +614,14 @@
   return cpu_temps;
 }
 
+cros_healthd::KeylockerInfoPtr CreateKeylockerInfo() {
+  return cros_healthd::KeylockerInfo::New(kFakeKeylockerConfigurationState);
+}
+
 cros_healthd::CpuResultPtr CreateCpuResult() {
   return cros_healthd::CpuResult::NewCpuInfo(cros_healthd::CpuInfo::New(
       kFakeNumTotalThreads, kFakeMojoArchitecture, CreatePhysicalCpu(),
-      CreateTemperatureChannel()));
+      CreateTemperatureChannel(), CreateKeylockerInfo()));
 }
 
 cros_healthd::TimezoneResultPtr CreateTimezoneResult() {
@@ -938,7 +943,18 @@
     RestartStatusCollector();
     // Disable network interface reporting since it requires additional setup.
     scoped_testing_cros_settings_.device_settings()->SetBoolean(
-        chromeos::kReportDeviceNetworkInterfaces, false);
+        chromeos::kReportDeviceNetworkStatus, false);
+    scoped_testing_cros_settings_.device_settings()->SetBoolean(
+        chromeos::kReportDeviceNetworkConfiguration, false);
+  }
+
+  void IsolateReportingSetting(const std::string& isolated_path) {
+    for (int i = 0; chromeos::kDeviceReportingSettings[i] != nullptr; i++) {
+      scoped_testing_cros_settings_.device_settings()->SetBoolean(
+          chromeos::kDeviceReportingSettings[i], false);
+    }
+    scoped_testing_cros_settings_.device_settings()->SetBoolean(isolated_path,
+                                                                true);
   }
 
   void TearDown() override { status_collector_.reset(); }
@@ -3883,15 +3899,21 @@
     ASSERT_EQ(base::size(kFakeNetworks), state_list.size());
   }
 
-  void SetReportDeviceNetworkInterfacesPolicy(bool enable) {
-    scoped_testing_cros_settings_.device_settings()->SetBoolean(
-        chromeos::kReportDeviceNetworkInterfaces, enable);
-  }
-
   void TearDown() override {
     DeviceStatusCollectorTest::TearDown();
   }
 
+  void ClearNetworkData() {
+    chromeos::ShillDeviceClient::TestInterface* device_client =
+        network_handler_test_helper_.device_test();
+    chromeos::ShillServiceClient::TestInterface* service_client =
+        network_handler_test_helper_.service_test();
+
+    device_client->ClearDevices();
+    service_client->ClearServices();
+    base::RunLoop().RunUntilIdle();
+  }
+
   virtual void VerifyReporting() = 0;
 
  private:
@@ -3935,6 +3957,15 @@
   }
 };
 
+TEST_F(DeviceStatusCollectorNetworkInterfacesTest, TestNoInterfaces) {
+  ClearNetworkData();
+  IsolateReportingSetting(chromeos::kReportDeviceNetworkConfiguration);
+
+  // If no interfaces are found, nothing should be reported.
+  GetStatus();
+  EXPECT_EQ(device_status_.SerializeAsString(), "");
+}
+
 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, Default) {
   // Network interfaces should be reported by default, i.e if the policy is not
   // set.
@@ -3942,19 +3973,22 @@
   VerifyReporting();
 
   // Network interfaces should be reported if the policy is set to true.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkConfiguration, true);
   GetStatus();
   VerifyReporting();
 
   // Network interfaces should not be reported if the policy is set to false.
-  SetReportDeviceNetworkInterfacesPolicy(false);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkConfiguration, false);
   GetStatus();
   EXPECT_EQ(0, device_status_.network_interfaces_size());
 }
 
 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, IfUnaffiliatedUser) {
   // Network interfaces should be reported for unaffiliated users.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkConfiguration, true);
   const AccountId account_id0(AccountId::FromUserEmail("user0@managed.com"));
   user_manager_->AddUserWithAffiliationAndType(account_id0, false,
                                                user_manager::USER_TYPE_REGULAR);
@@ -3964,7 +3998,8 @@
 
 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, IfAffiliatedUser) {
   // Network interfaces should be reported for affiliated users.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkConfiguration, true);
   const AccountId account_id0(AccountId::FromUserEmail("user0@managed.com"));
   user_manager_->AddUserWithAffiliationAndType(account_id0, true,
                                                user_manager::USER_TYPE_REGULAR);
@@ -3974,7 +4009,8 @@
 
 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, IfPublicSession) {
   // Network interfaces should be reported if in public session.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkConfiguration, true);
   user_manager_->CreatePublicAccountUser(
       AccountId::FromUserEmail(kPublicAccountId));
   EXPECT_CALL(*user_manager_, IsLoggedInAsPublicAccount())
@@ -3986,7 +4022,8 @@
 
 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, IfKioskMode) {
   // Network interfaces should be reported if in kiosk mode.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkConfiguration, true);
   user_manager_->CreateKioskAppUser(AccountId::FromUserEmail(kKioskAccountId));
   EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp())
       .WillRepeatedly(Return(true));
@@ -4035,8 +4072,9 @@
   GetStatus();
   EXPECT_EQ(0, device_status_.network_states_size());
 
-  SetReportDeviceNetworkInterfacesPolicy(true);
   // Mock that the device is in kiosk mode to report network state.
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkStatus, true);
   user_manager_->CreateKioskAppUser(AccountId::FromUserEmail(kKioskAccountId));
   EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp())
       .WillRepeatedly(Return(true));
@@ -4045,19 +4083,31 @@
   VerifyReporting();
 
   // Network state should not be reported if the policy is set to false.
-  SetReportDeviceNetworkInterfacesPolicy(false);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkStatus, false);
   GetStatus();
   EXPECT_EQ(0, device_status_.network_states_size());
 
   // Network state should be reported if the policy is set to true.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkStatus, true);
   GetStatus();
   VerifyReporting();
 }
 
+TEST_F(DeviceStatusCollectorNetworkStateTest, TestNoNetworks) {
+  ClearNetworkData();
+  IsolateReportingSetting(chromeos::kReportDeviceNetworkStatus);
+
+  // If no networks are found, nothing should be reported.
+  GetStatus();
+  EXPECT_EQ(device_status_.SerializeAsString(), "");
+}
+
 TEST_F(DeviceStatusCollectorNetworkStateTest, IfUnaffiliatedUser) {
   // Network state shouldn't be reported for unaffiliated users.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkStatus, true);
   const AccountId account_id0(AccountId::FromUserEmail("user0@managed.com"));
   user_manager_->AddUserWithAffiliationAndType(account_id0, false,
                                                user_manager::USER_TYPE_REGULAR);
@@ -4067,7 +4117,8 @@
 
 TEST_F(DeviceStatusCollectorNetworkStateTest, IfAffiliatedUser) {
   // Network state should be reported for affiliated users.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkStatus, true);
   const AccountId account_id0(AccountId::FromUserEmail("user0@managed.com"));
   user_manager_->AddUserWithAffiliationAndType(account_id0, true,
                                                user_manager::USER_TYPE_REGULAR);
@@ -4077,7 +4128,8 @@
 
 TEST_F(DeviceStatusCollectorNetworkStateTest, IfPublicSession) {
   // Network state should be reported if in public session.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkStatus, true);
   user_manager_->CreatePublicAccountUser(
       AccountId::FromUserEmail(kPublicAccountId));
   EXPECT_CALL(*user_manager_, IsLoggedInAsPublicAccount())
@@ -4089,7 +4141,8 @@
 
 TEST_F(DeviceStatusCollectorNetworkStateTest, IfKioskMode) {
   // Network state should be reported if in kiosk mode.
-  SetReportDeviceNetworkInterfacesPolicy(true);
+  scoped_testing_cros_settings_.device_settings()->SetBoolean(
+      chromeos::kReportDeviceNetworkStatus, true);
   user_manager_->CreateKioskAppUser(AccountId::FromUserEmail(kKioskAccountId));
   EXPECT_CALL(*user_manager_, IsLoggedInAsKioskApp())
       .WillRepeatedly(Return(true));
diff --git a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
index 7e4e1131..bb95f724 100644
--- a/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
+++ b/chrome/browser/ash/policy/status_collector/legacy_device_status_collector_browsertest.cc
@@ -193,6 +193,7 @@
     cros_healthd::CpuArchitectureEnum::kX86_64;
 constexpr em::CpuInfo::Architecture kFakeProtoArchitecture =
     em::CpuInfo::X86_64;
+constexpr bool kFakeKeylockerConfigurationState = false;
 constexpr uint32_t kFakeMaxClockSpeed = 3400000;
 constexpr uint32_t kFakeScalingMaxFrequency = 2700000;
 constexpr uint32_t kFakeScalingCurFrequency = 2400000;
@@ -615,10 +616,14 @@
   return cpu_temps;
 }
 
+cros_healthd::KeylockerInfoPtr CreateKeylockerInfo() {
+  return cros_healthd::KeylockerInfo::New(kFakeKeylockerConfigurationState);
+}
+
 cros_healthd::CpuResultPtr CreateCpuResult() {
   return cros_healthd::CpuResult::NewCpuInfo(cros_healthd::CpuInfo::New(
       kFakeNumTotalThreads, kFakeMojoArchitecture, CreatePhysicalCpu(),
-      CreateTemperatureChannel()));
+      CreateTemperatureChannel(), CreateKeylockerInfo()));
 }
 
 cros_healthd::TimezoneResultPtr CreateTimezoneResult() {
@@ -4151,4 +4156,4 @@
   VerifyReporting();
 }
 
-}  // namespace policy
\ No newline at end of file
+}  // namespace policy
diff --git a/chrome/browser/ash/usb/cros_usb_detector.cc b/chrome/browser/ash/usb/cros_usb_detector.cc
index 587e841..3cb4ccc8 100644
--- a/chrome/browser/ash/usb/cros_usb_detector.cc
+++ b/chrome/browser/ash/usb/cros_usb_detector.cc
@@ -31,6 +31,7 @@
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/disks/disk.h"
 #include "chromeos/disks/disk_mount_manager.h"
+#include "components/arc/arc_features.h"
 #include "components/arc/arc_util.h"
 #include "components/prefs/scoped_user_pref_update.h"
 #include "components/vector_icons/vector_icons.h"
@@ -588,6 +589,20 @@
 
   SignalUsbDeviceObservers();
 
+  // Temporarily allow User to attach un claimed USB devices to ARC VM.
+  // This part as well as the emperiment flag should go away once UI permission
+  // is integrated in |ShowNotificationForDevice|.
+  if (arc::IsArcVmEnabled() &&
+      base::FeatureList::IsEnabled(arc::kUsbDeviceDefaultAttachToArcVm)) {
+    if (has_supported_interface || new_device.allowed_interfaces_mask != 0) {
+      // USB devices not claimed by Chrome OS get automatically attached to the
+      // ARCVM. Note that this relies on the underlying VM (ARCVM) having
+      // its own permission model to restrict access to the device.
+      AttachUsbDeviceToVm(arc::kArcVmName, guid, base::DoNothing());
+      return;
+    }
+  }
+
   // Some devices should not trigger the notification.
   if (hide_notification || !ShouldShowNotification(result.first->second)) {
     VLOG(1) << "Not showing USB notification for " << label;
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc
index cb2d625..515fc1e 100644
--- a/chrome/browser/autofill/autofill_browsertest.cc
+++ b/chrome/browser/autofill/autofill_browsertest.cc
@@ -718,7 +718,9 @@
 // Test that autocomplete available string attribute is correctly set on
 // accessibility node. Test autocomplete in this file since it uses the same
 // infrastructure as autofill.
-IN_PROC_BROWSER_TEST_F(AutofillAccessibilityTest, TestAutocompleteState) {
+// Test is flaky: http://crbug.com/1239099
+IN_PROC_BROWSER_TEST_F(AutofillAccessibilityTest,
+                       DISABLED_TestAutocompleteState) {
   content::BrowserAccessibilityState::GetInstance()->EnableAccessibility();
   // Navigate to url and wait for accessibility notification
   GURL url =
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index c9dc338..d1bb0707 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -137,6 +137,7 @@
 #include "chrome/browser/ui/passwords/well_known_change_password_navigation_throttle.h"
 #include "chrome/browser/ui/prefs/pref_watcher.h"
 #include "chrome/browser/ui/tab_contents/chrome_web_contents_view_delegate.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/webid/identity_dialog_controller.h"
 #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
 #include "chrome/browser/ui/webui/log_web_ui_url.h"
@@ -582,6 +583,11 @@
 #include "chrome/browser/component_updater/hyphenation_component_installer.h"
 #endif
 
+#if BUILDFLAG(ENABLE_SIDE_SEARCH)
+#include "chrome/browser/ui/side_search/side_search_side_contents_helper.h"
+#include "chrome/browser/ui/side_search/side_search_utils.h"
+#endif  // BUILDFLAG(ENABLE_SIDE_SEARCH)
+
 #if defined(_WINDOWS_)
 // This source file doesn't need windows.h and its associated namespace
 // pollution. Try to avoid windows.h in header files used by source files such
@@ -4181,6 +4187,14 @@
         &throttles);
   }
 
+#if BUILDFLAG(ENABLE_SIDE_SEARCH)
+  if (profile && IsSideSearchEnabled(profile)) {
+    MaybeAddThrottle(
+        SideSearchSideContentsHelper::MaybeCreateThrottleFor(handle),
+        &throttles);
+  }
+#endif  // BUILDFLAG(ENABLE_SIDE_SEARCH)
+
   return throttles;
 }
 
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
index c7512ca..dee74e7 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.cc
@@ -9,6 +9,7 @@
 #include <utility>
 
 #include "base/callback.h"
+#include "base/files/file_path.h"
 #include "base/location.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/fake_hardware_info_delegate.h"
@@ -23,9 +24,8 @@
 
 namespace chromeos {
 
-namespace {
-
-constexpr char kManifest[] = R"(
+// static
+const char BaseTelemetryExtensionBrowserTest::kManifestFile[] = R"(
       {
         // Sample telemetry extension public key. Currently, this is the only
         // allowed extension to declare "chromeos_system_extension" key.
@@ -44,12 +44,11 @@
           "matches": [
             "http://www.google.com/*"
           ]
-        }
+        },
+        "options_page": "options.html"
       }
     )";
 
-}  // namespace
-
 // static
 const char BaseTelemetryExtensionBrowserTest::kPwaPageUrlString[] =
     "http://www.google.com";
@@ -83,35 +82,18 @@
   }
 }
 
-const extensions::Extension*
-BaseTelemetryExtensionBrowserTest::LoadExtensionWithManifestAndServiceWorker(
-    extensions::TestExtensionDir& test_dir,
-    const std::string& manifest_content,
-    const std::string& service_worker_content) {
-  test_dir.WriteManifest(manifest_content);
-  test_dir.WriteFile(FILE_PATH_LITERAL("sw.js"), service_worker_content);
-
-  return LoadExtension(test_dir.UnpackedPath());
-}
-
-const extensions::Extension*
-BaseTelemetryExtensionBrowserTest::LoadExtensionWithServiceWorker(
-    extensions::TestExtensionDir& test_dir,
-    const std::string& service_worker_content) {
-  return LoadExtensionWithManifestAndServiceWorker(test_dir, kManifest,
-                                                   service_worker_content);
-}
-
 void BaseTelemetryExtensionBrowserTest::CreateExtensionAndRunServiceWorker(
     const std::string& service_worker_content) {
   // Must outlive the extension.
   extensions::TestExtensionDir test_dir;
+  test_dir.WriteManifest(kManifestFile);
+  test_dir.WriteFile(FILE_PATH_LITERAL("sw.js"), service_worker_content);
+  test_dir.WriteFile(FILE_PATH_LITERAL("options.html"), "");
 
   // Must be initialised before loading extension.
   extensions::ResultCatcher result_catcher;
 
-  const auto* extension = LoadExtensionWithManifestAndServiceWorker(
-      test_dir, kManifest, service_worker_content);
+  const auto* extension = LoadExtension(test_dir.UnpackedPath());
   ASSERT_TRUE(extension);
 
   EXPECT_TRUE(result_catcher.GetNextResult()) << result_catcher.message();
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h
index 943d81a..93790c7 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h
@@ -10,17 +10,13 @@
 #include "chrome/browser/chromeos/extensions/telemetry/api/hardware_info_delegate.h"
 #include "chrome/browser/extensions/extension_browsertest.h"
 #include "content/public/browser/render_frame_host.h"
-#include "extensions/test/test_extension_dir.h"
-
-namespace extensions {
-class Extension;
-}  // namespace extensions
 
 namespace chromeos {
 
 class BaseTelemetryExtensionBrowserTest
     : public extensions::ExtensionBrowserTest {
  public:
+  static const char kManifestFile[];
   static const char kPwaPageUrlString[];
 
   BaseTelemetryExtensionBrowserTest();
@@ -35,13 +31,6 @@
   void SetUpOnMainThread() override;
 
  protected:
-  const extensions::Extension* LoadExtensionWithManifestAndServiceWorker(
-      extensions::TestExtensionDir& test_dir,
-      const std::string& manifest_content,
-      const std::string& service_worker_content);
-  const extensions::Extension* LoadExtensionWithServiceWorker(
-      extensions::TestExtensionDir& test_dir,
-      const std::string& service_worker_content);
   void CreateExtensionAndRunServiceWorker(
       const std::string& service_worker_content);
 
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc
index bd2e946..6b2eef1 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/telemetry_extension_capabilities_browser_test.cc
@@ -3,12 +3,16 @@
 // found in the LICENSE file.
 
 #include "base/callback_helpers.h"
+#include "base/files/file_path.h"
 #include "base/strings/stringprintf.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/test/browser_test.h"
+#include "extensions/common/manifest_handlers/options_page_info.h"
 #include "extensions/test/extension_test_message_listener.h"
+#include "extensions/test/test_extension_dir.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
 
@@ -36,10 +40,9 @@
 
   // Must outlive the extension.
   extensions::TestExtensionDir test_dir_receiver;
-
-  // Load and run the extenion (chromeos_system_extension).
-  const extensions::Extension* receiver = LoadExtensionWithServiceWorker(
-      test_dir_receiver, base::StringPrintf(R"(
+  test_dir_receiver.WriteManifest(kManifestFile);
+  test_dir_receiver.WriteFile(FILE_PATH_LITERAL("options.html"), "");
+  test_dir_receiver.WriteFile("sw.js", base::StringPrintf(R"(
         chrome.test.runTests([
           function runtimeOnMessageExternal() {
             chrome.runtime.onMessageExternal.addListener(
@@ -52,6 +55,10 @@
           }
         ]);
       )", kPwaPageUrlString));
+
+  // Load and run the extenion (chromeos_system_extension).
+  const extensions::Extension* receiver =
+      LoadExtension(test_dir_receiver.UnpackedPath());
   ASSERT_TRUE(receiver);
 
   // Make sure the extension is ready.
@@ -74,4 +81,39 @@
   EXPECT_EQ("success", listener.message());
 }
 
+// Tests that chromeos_system_extension is able to define options_page manifest
+// key and user can navigate to the options page.
+IN_PROC_BROWSER_TEST_F(TelemetryExtensionBrowserTest,
+                       CanNavigateToOptionsPage) {
+  // Start listening on the extension.
+  ExtensionTestMessageListener listener(/*will_reply=*/false);
+
+  // Must outlive the extension.
+  extensions::TestExtensionDir test_dir;
+  test_dir.WriteManifest(kManifestFile);
+  test_dir.WriteFile(FILE_PATH_LITERAL("options.html"),
+                     "<script>chrome.test.sendMessage('done')</script>");
+  test_dir.WriteFile("sw.js", "chrome.test.sendMessage('ready');");
+
+  // Load and run the extenion (chromeos_system_extension).
+  const extensions::Extension* extension =
+      LoadExtension(test_dir.UnpackedPath());
+  ASSERT_TRUE(extension);
+
+  // Make sure the extension is ready.
+  ASSERT_TRUE(listener.WaitUntilSatisfied());
+  EXPECT_EQ("ready", listener.message());
+
+  listener.Reset();
+
+  // Navigate to the extension's options page.
+  ASSERT_TRUE(extensions::OptionsPageInfo::HasOptionsPage(extension));
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(
+      browser(), extensions::OptionsPageInfo::GetOptionsPage(extension)));
+
+  // Wait until the extension's options page is loaded.
+  ASSERT_TRUE(listener.WaitUntilSatisfied());
+  EXPECT_EQ("done", listener.message());
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/commerce/merchant_viewer/android/BUILD.gn b/chrome/browser/commerce/merchant_viewer/android/BUILD.gn
index d814482c..086af39 100644
--- a/chrome/browser/commerce/merchant_viewer/android/BUILD.gn
+++ b/chrome/browser/commerce/merchant_viewer/android/BUILD.gn
@@ -24,6 +24,7 @@
     "java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsMediator.java",
     "java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsStorageFactory.java",
     "java/src/org/chromium/chrome/browser/merchant_viewer/MerchantViewerConfig.java",
+    "java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java",
     "java/src/org/chromium/chrome/browser/merchant_viewer/RatingStarSpan.java",
     "java/src/org/chromium/chrome/browser/merchant_viewer/WebContentsHelpers.java",
   ]
@@ -51,6 +52,8 @@
     "//components/embedder_support/android:web_contents_delegate_java",
     "//components/messages/android:java",
     "//components/optimization_guide/proto:optimization_guide_proto_java",
+    "//components/page_info/android:java",
+    "//components/page_info/android:page_info_action_enum_java",
     "//components/prefs/android:java",
     "//components/security_state/content/android:java",
     "//components/security_state/core:security_state_enums_java",
@@ -144,14 +147,17 @@
     "javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewTest.java",
     "javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsEventLoadCallbackHelper.java",
     "javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsEventStorageTest.java",
+    "javatests/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoViewTest.java",
   ]
 
   deps = [
     "//base:base_java",
     "//base:base_java_test_support",
+    "//chrome/android:chrome_java",
     "//chrome/browser/commerce/merchant_viewer:optimization_guide_protos_java",
     "//chrome/browser/commerce/merchant_viewer/android:java",
     "//chrome/browser/flags:java",
+    "//chrome/browser/optimization_guide/android:java",
     "//chrome/browser/profiles/android:java",
     "//chrome/browser/tabmodel:java",
     "//chrome/test/android:chrome_java_test_support",
@@ -159,14 +165,20 @@
     "//components/embedder_support/android:content_view_java",
     "//components/messages/android:java",
     "//components/messages/android/internal:java",
+    "//components/optimization_guide/proto:optimization_guide_proto_java",
+    "//components/page_info/android:java",
+    "//components/page_info/android:page_info_action_enum_java",
     "//components/thin_webview:java",
     "//components/url_formatter/android:url_formatter_java",
     "//content/public/android:content_full_java",
     "//content/public/test/android:content_java_test_support",
+    "//third_party/android_deps:espresso_java",
+    "//third_party/android_deps:protobuf_lite_runtime_java",
     "//third_party/android_support_test_runner:runner_java",
     "//third_party/androidx:androidx_appcompat_appcompat_resources_java",
     "//third_party/androidx:androidx_test_core_java",
     "//third_party/androidx:androidx_test_runner_java",
+    "//third_party/hamcrest:hamcrest_core_java",
     "//third_party/junit",
     "//third_party/mockito:mockito_java",
     "//ui/android:ui_java_test_support",
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java
index cb037318..c48d115 100644
--- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java
+++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustMessageViewModel.java
@@ -35,7 +35,7 @@
                 .with(MessageBannerProperties.MESSAGE_IDENTIFIER, MessageIdentifier.MERCHANT_TRUST)
                 .with(MessageBannerProperties.ICON,
                         ResourcesCompat.getDrawable(context.getResources(),
-                                R.drawable.ic_logo_googleg_24dp, context.getTheme()))
+                                R.drawable.ic_storefront_blue, context.getTheme()))
                 .with(MessageBannerProperties.ICON_TINT_COLOR, MessageBannerProperties.TINT_NONE)
                 .with(MessageBannerProperties.TITLE,
                         context.getResources().getString(R.string.merchant_viewer_message_title))
@@ -49,7 +49,7 @@
                 .build();
     }
 
-    private static Spannable getMessageDescription(
+    public static Spannable getMessageDescription(
             Context context, MerchantTrustSignals trustSignals) {
         SpannableStringBuilder builder = new SpannableStringBuilder();
         NumberFormat numberFormatter = NumberFormat.getIntegerInstance();
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java
index 0d387346..decb003 100644
--- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java
+++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinator.java
@@ -34,7 +34,8 @@
 /**
  * Coordinator for managing merchant trust signals experience.
  */
-public class MerchantTrustSignalsCoordinator {
+public class MerchantTrustSignalsCoordinator
+        implements PageInfoStoreInfoController.StoreInfoActionHandler {
     private final MerchantTrustSignalsMediator mMediator;
     private final MerchantTrustMessageScheduler mMessageScheduler;
     private final MerchantTrustBottomSheetCoordinator mDetailsTabCoordinator;
@@ -173,6 +174,11 @@
         launchDetailsPage(new GURL(trustSignals.getMerchantDetailsPageUrl()));
     }
 
+    @Override
+    public void onStoreInfoClicked(MerchantTrustSignals trustSignals) {
+        launchDetailsPage(new GURL(trustSignals.getMerchantDetailsPageUrl()));
+    }
+
     private void launchDetailsPage(GURL url) {
         mDetailsTabCoordinator.requestOpenSheet(url,
                 mContext.getResources().getString(R.string.merchant_viewer_preview_sheet_title));
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProvider.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProvider.java
index 9793ad7..ff630f9 100644
--- a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProvider.java
+++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProvider.java
@@ -3,13 +3,17 @@
 // found in the LICENSE file.
 package org.chromium.chrome.browser.merchant_viewer;
 
+import androidx.annotation.Nullable;
+
 import org.chromium.base.Callback;
 import org.chromium.base.Log;
 import org.chromium.chrome.browser.merchant_viewer.proto.MerchantTrustSignalsOuterClass.MerchantTrustSignals;
 import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridgeFactory;
 import org.chromium.components.optimization_guide.OptimizationGuideDecision;
+import org.chromium.components.optimization_guide.proto.CommonTypesProto.Any;
 import org.chromium.components.optimization_guide.proto.HintsProto;
 import org.chromium.content_public.browser.NavigationHandle;
+import org.chromium.url.GURL;
 
 import java.io.IOException;
 import java.util.Arrays;
@@ -23,32 +27,46 @@
             new OptimizationGuideBridgeFactory(
                     Arrays.asList(HintsProto.OptimizationType.MERCHANT_TRUST_SIGNALS));
 
-    /** Fetches {@link MerchantTrustSignals} through {@link OptimizationGuideBridge}. */
+    /**
+     * Fetches {@link MerchantTrustSignals} through {@link OptimizationGuideBridge} based on {@link
+     * NavigationHandle}.
+     */
     public void getDataForNavigationHandle(
             NavigationHandle navigationHandle, Callback<MerchantTrustSignals> callback) {
         sOptimizationGuideBridgeFactory.create().canApplyOptimizationAsync(navigationHandle,
                 HintsProto.OptimizationType.MERCHANT_TRUST_SIGNALS, (decision, metadata) -> {
-                    if (decision != OptimizationGuideDecision.TRUE || metadata == null) {
-                        callback.onResult(null);
-                        return;
-                    }
-                    try {
-                        MerchantTrustSignals trustSignals =
-                                MerchantTrustSignals.parseFrom(metadata.getValue());
-
-                        callback.onResult(
-                                isValidMerchantTrustSignals(trustSignals) ? trustSignals : null);
-                    } catch (IOException e) {
-                        // Catching Exception instead of InvalidProtocolBufferException in order to
-                        // avoid increasing the apk size by taking a dependency on protobuf lib.
-                        Log.i(TAG,
-                                "There was a problem parsing MerchantTrustSignals."
-                                        + e.getMessage());
-                        callback.onResult(null);
-                    }
+                    onOptimizationGuideDecision(decision, metadata, callback);
                 });
     }
 
+    /**
+     * Fetches {@link MerchantTrustSignals} through {@link OptimizationGuideBridge} based on {@link
+     * GURL}.
+     */
+    public void getDataForUrl(GURL url, Callback<MerchantTrustSignals> callback) {
+        sOptimizationGuideBridgeFactory.create().canApplyOptimization(
+                url, HintsProto.OptimizationType.MERCHANT_TRUST_SIGNALS, (decision, metadata) -> {
+                    onOptimizationGuideDecision(decision, metadata, callback);
+                });
+    }
+
+    private void onOptimizationGuideDecision(@OptimizationGuideDecision int decision,
+            @Nullable Any metadata, Callback<MerchantTrustSignals> callback) {
+        if (decision != OptimizationGuideDecision.TRUE || metadata == null) {
+            callback.onResult(null);
+            return;
+        }
+        try {
+            MerchantTrustSignals trustSignals = MerchantTrustSignals.parseFrom(metadata.getValue());
+            callback.onResult(isValidMerchantTrustSignals(trustSignals) ? trustSignals : null);
+        } catch (IOException e) {
+            // Catching Exception instead of InvalidProtocolBufferException in order to
+            // avoid increasing the apk size by taking a dependency on protobuf lib.
+            Log.i(TAG, "There was a problem parsing MerchantTrustSignals." + e.getMessage());
+            callback.onResult(null);
+        }
+    }
+
     private boolean isValidMerchantTrustSignals(MerchantTrustSignals trustSignals) {
         return trustSignals.hasMerchantCountRating() && trustSignals.hasMerchantStarRating()
                 && trustSignals.hasMerchantDetailsPageUrl();
diff --git a/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java
new file mode 100644
index 0000000..1da3fa6
--- /dev/null
+++ b/chrome/browser/commerce/merchant_viewer/android/java/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoController.java
@@ -0,0 +1,93 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.merchant_viewer;
+
+import android.content.Context;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.Nullable;
+
+import org.chromium.base.supplier.Supplier;
+import org.chromium.chrome.browser.merchant_viewer.proto.MerchantTrustSignalsOuterClass.MerchantTrustSignals;
+import org.chromium.chrome.tab_ui.R;
+import org.chromium.components.page_info.PageInfoAction;
+import org.chromium.components.page_info.PageInfoMainController;
+import org.chromium.components.page_info.PageInfoRowView;
+import org.chromium.components.page_info.PageInfoSubpageController;
+
+/**
+ * Class for controlling the {@link ChromePageInfo} "store info" section.
+ */
+public class PageInfoStoreInfoController implements PageInfoSubpageController {
+    public static final int STORE_INFO_ROW_ID = View.generateViewId();
+
+    /** Handles the actions needed by the "store info" row. */
+    public interface StoreInfoActionHandler {
+        /** Called when the "store info" row is clicked. */
+        void onStoreInfoClicked(MerchantTrustSignals trustSignals);
+    }
+
+    private final Supplier<StoreInfoActionHandler> mActionHandlerSupplier;
+    private final PageInfoMainController mMainController;
+    private final PageInfoRowView mRowView;
+    private final Context mContext;
+
+    public PageInfoStoreInfoController(PageInfoMainController mainController,
+            PageInfoRowView rowView,
+            @Nullable Supplier<StoreInfoActionHandler> actionHandlerSupplier) {
+        mMainController = mainController;
+        mRowView = rowView;
+        mContext = mRowView.getContext();
+        mActionHandlerSupplier = actionHandlerSupplier;
+        new MerchantTrustSignalsDataProvider().getDataForUrl(
+                mMainController.getURL(), this::setupStoreInfoRow);
+    }
+
+    private void setupStoreInfoRow(@Nullable MerchantTrustSignals trustSignals) {
+        PageInfoRowView.ViewParams rowParams = new PageInfoRowView.ViewParams();
+        if (mActionHandlerSupplier == null || mActionHandlerSupplier.get() == null
+                || trustSignals == null) {
+            rowParams.visible = false;
+        } else {
+            rowParams.visible = true;
+            rowParams.title =
+                    mContext.getResources().getString(R.string.page_info_store_info_title);
+            rowParams.subtitle = getRowSubtitle(trustSignals);
+            // The icons in PageInfo are tinted automatically.
+            rowParams.iconResId = R.drawable.ic_storefront_blue;
+            rowParams.clickCallback = () -> {
+                mMainController.recordAction(PageInfoAction.PAGE_INFO_STORE_INFO_CLICKED);
+                mActionHandlerSupplier.get().onStoreInfoClicked(trustSignals);
+            };
+        }
+        mRowView.setParams(rowParams);
+    }
+
+    private CharSequence getRowSubtitle(MerchantTrustSignals trustSignals) {
+        // TODO(zhiyuancai): Set subtitle based on trustSignals after updating the proto.
+        return MerchantTrustMessageViewModel.getMessageDescription(mContext, trustSignals);
+    }
+
+    // PageInfoSubpageController implementations. We don't use subpage for "store info" row.
+    @Override
+    public String getSubpageTitle() {
+        return "";
+    }
+
+    @Override
+    public View createViewForSubpage(ViewGroup parent) {
+        return null;
+    }
+
+    @Override
+    public void onSubpageRemoved() {}
+
+    @Override
+    public void clearData() {}
+
+    @Override
+    public void updateRowIfNeeded() {}
+}
\ No newline at end of file
diff --git a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java
index cc532e74..030c807 100644
--- a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java
+++ b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsCoordinatorTest.java
@@ -443,6 +443,14 @@
 
     @SmallTest
     @Test
+    public void testOnStoreInfoClicked() {
+        mCoordinator.onStoreInfoClicked(mDummyMerchantTrustSignals);
+        verify(mMockDetailsTabCoordinator, times(1))
+                .requestOpenSheet(any(GURL.class), any(String.class));
+    }
+
+    @SmallTest
+    @Test
     public void testOnlyAbleToShowThreeMessagesInGivenTime() {
         mTestValues.addFieldTrialParamOverride(ChromeFeatureList.COMMERCE_MERCHANT_VIEWER,
                 MerchantViewerConfig.TRUST_SIGNALS_MAX_ALLOWED_NUMBER_IN_GIVEN_WINDOW_PARAM, "3");
diff --git a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProviderTest.java b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProviderTest.java
index 0cf6367..3b0b29b 100644
--- a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProviderTest.java
+++ b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/MerchantTrustSignalsDataProviderTest.java
@@ -95,7 +95,7 @@
         int callCount = callbackHelper.getCallCount();
         mockOptimizationGuideResponse(mMockOptimizationGuideBridgeJni,
                 OptimizationGuideDecision.FALSE, ANY_MERHCANT_TRUST_SIGNALS);
-        instance.getDataForNavigationHandle(mNavigationHandle, callbackHelper::notifyCalled);
+        instance.getDataForUrl(mMockDestinationGurl, callbackHelper::notifyCalled);
         callbackHelper.waitForCallback(callCount);
         Assert.assertNull(callbackHelper.getMerchantTrustSignalsResult());
     }
@@ -110,7 +110,7 @@
         int callCount = callbackHelper.getCallCount();
         mockOptimizationGuideResponse(
                 mMockOptimizationGuideBridgeJni, OptimizationGuideDecision.TRUE, null);
-        instance.getDataForNavigationHandle(mNavigationHandle, callbackHelper::notifyCalled);
+        instance.getDataForUrl(mMockDestinationGurl, callbackHelper::notifyCalled);
         callbackHelper.waitForCallback(callCount);
         Assert.assertNull(callbackHelper.getMerchantTrustSignalsResult());
     }
@@ -125,7 +125,7 @@
         int callCount = callbackHelper.getCallCount();
         mockOptimizationGuideResponse(mMockOptimizationGuideBridgeJni,
                 OptimizationGuideDecision.TRUE, Any.getDefaultInstance());
-        instance.getDataForNavigationHandle(mNavigationHandle, callbackHelper::notifyCalled);
+        instance.getDataForUrl(mMockDestinationGurl, callbackHelper::notifyCalled);
         callbackHelper.waitForCallback(callCount);
         Assert.assertNull(callbackHelper.getMerchantTrustSignalsResult());
     }
@@ -140,6 +140,71 @@
         int callCount = callbackHelper.getCallCount();
         mockOptimizationGuideResponse(mMockOptimizationGuideBridgeJni,
                 OptimizationGuideDecision.TRUE, ANY_MERHCANT_TRUST_SIGNALS);
+        instance.getDataForUrl(mMockDestinationGurl, callbackHelper::notifyCalled);
+        callbackHelper.waitForCallback(callCount);
+
+        MerchantTrustSignals result = callbackHelper.getMerchantTrustSignalsResult();
+        Assert.assertNotNull(result);
+        Assert.assertEquals(4.5f, result.getMerchantStarRating(), 0.0f);
+        Assert.assertEquals(100, result.getMerchantCountRating());
+        Assert.assertEquals("http://dummy/url", result.getMerchantDetailsPageUrl());
+    }
+
+    @Test
+    public void testGetDataForNavigationHandlerNoMetadata() throws TimeoutException {
+        MerchantTrustSignalsDataProvider instance = getDataProvider();
+
+        MerchantTrustSignalsCallbackHelper callbackHelper =
+                new MerchantTrustSignalsCallbackHelper();
+
+        int callCount = callbackHelper.getCallCount();
+        mockOptimizationGuideAsyncResponse(mMockOptimizationGuideBridgeJni,
+                OptimizationGuideDecision.FALSE, ANY_MERHCANT_TRUST_SIGNALS);
+        instance.getDataForNavigationHandle(mNavigationHandle, callbackHelper::notifyCalled);
+        callbackHelper.waitForCallback(callCount);
+        Assert.assertNull(callbackHelper.getMerchantTrustSignalsResult());
+    }
+
+    @Test
+    public void testGetDataForNavigationHandlerNullMetadata() throws TimeoutException {
+        MerchantTrustSignalsDataProvider instance = getDataProvider();
+
+        MerchantTrustSignalsCallbackHelper callbackHelper =
+                new MerchantTrustSignalsCallbackHelper();
+
+        int callCount = callbackHelper.getCallCount();
+        mockOptimizationGuideAsyncResponse(
+                mMockOptimizationGuideBridgeJni, OptimizationGuideDecision.TRUE, null);
+        instance.getDataForNavigationHandle(mNavigationHandle, callbackHelper::notifyCalled);
+        callbackHelper.waitForCallback(callCount);
+        Assert.assertNull(callbackHelper.getMerchantTrustSignalsResult());
+    }
+
+    @Test
+    public void testGetDataForNavigationHandlerInvalidMetadata() throws TimeoutException {
+        MerchantTrustSignalsDataProvider instance = getDataProvider();
+
+        MerchantTrustSignalsCallbackHelper callbackHelper =
+                new MerchantTrustSignalsCallbackHelper();
+
+        int callCount = callbackHelper.getCallCount();
+        mockOptimizationGuideAsyncResponse(mMockOptimizationGuideBridgeJni,
+                OptimizationGuideDecision.TRUE, Any.getDefaultInstance());
+        instance.getDataForNavigationHandle(mNavigationHandle, callbackHelper::notifyCalled);
+        callbackHelper.waitForCallback(callCount);
+        Assert.assertNull(callbackHelper.getMerchantTrustSignalsResult());
+    }
+
+    @Test
+    public void testGetDataForNavigationHandlerValid() throws TimeoutException {
+        MerchantTrustSignalsDataProvider instance = getDataProvider();
+
+        MerchantTrustSignalsCallbackHelper callbackHelper =
+                new MerchantTrustSignalsCallbackHelper();
+
+        int callCount = callbackHelper.getCallCount();
+        mockOptimizationGuideAsyncResponse(mMockOptimizationGuideBridgeJni,
+                OptimizationGuideDecision.TRUE, ANY_MERHCANT_TRUST_SIGNALS);
         instance.getDataForNavigationHandle(mNavigationHandle, callbackHelper::notifyCalled);
         callbackHelper.waitForCallback(callCount);
 
@@ -150,6 +215,23 @@
         Assert.assertEquals("http://dummy/url", result.getMerchantDetailsPageUrl());
     }
 
+    static void mockOptimizationGuideAsyncResponse(
+            OptimizationGuideBridge.Natives optimizationGuideJni,
+            @OptimizationGuideDecision int decision, Any metadata) {
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) {
+                OptimizationGuideCallback callback =
+                        (OptimizationGuideCallback) invocation.getArguments()[3];
+                callback.onOptimizationGuideDecision(decision, metadata);
+                return null;
+            }
+        })
+                .when(optimizationGuideJni)
+                .canApplyOptimizationAsync(
+                        anyLong(), any(GURL.class), anyInt(), any(OptimizationGuideCallback.class));
+    }
+
     static void mockOptimizationGuideResponse(OptimizationGuideBridge.Natives optimizationGuideJni,
             @OptimizationGuideDecision int decision, Any metadata) {
         doAnswer(new Answer<Void>() {
@@ -162,7 +244,7 @@
             }
         })
                 .when(optimizationGuideJni)
-                .canApplyOptimizationAsync(
+                .canApplyOptimization(
                         anyLong(), any(GURL.class), anyInt(), any(OptimizationGuideCallback.class));
     }
 
diff --git a/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoViewTest.java b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoViewTest.java
new file mode 100644
index 0000000..c9c69c7
--- /dev/null
+++ b/chrome/browser/commerce/merchant_viewer/android/javatests/src/org/chromium/chrome/browser/merchant_viewer/PageInfoStoreInfoViewTest.java
@@ -0,0 +1,196 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.merchant_viewer;
+
+import static androidx.test.espresso.Espresso.onView;
+import static androidx.test.espresso.action.ViewActions.click;
+import static androidx.test.espresso.assertion.ViewAssertions.matches;
+import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
+import static androidx.test.espresso.matcher.ViewMatchers.withId;
+
+import static org.hamcrest.CoreMatchers.allOf;
+import static org.hamcrest.CoreMatchers.not;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import static org.chromium.ui.test.util.ViewUtils.onViewWaiting;
+
+import androidx.test.filters.MediumTest;
+
+import com.google.protobuf.ByteString;
+
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.stubbing.Answer;
+
+import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisabledTest;
+import org.chromium.base.test.util.Feature;
+import org.chromium.base.test.util.JniMocker;
+import org.chromium.base.test.util.Restriction;
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.app.ChromeActivity;
+import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.merchant_viewer.PageInfoStoreInfoController.StoreInfoActionHandler;
+import org.chromium.chrome.browser.merchant_viewer.proto.MerchantTrustSignalsOuterClass.MerchantTrustSignals;
+import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridge;
+import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridge.OptimizationGuideCallback;
+import org.chromium.chrome.browser.optimization_guide.OptimizationGuideBridgeJni;
+import org.chromium.chrome.browser.page_info.ChromePageInfo;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
+import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
+import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
+import org.chromium.chrome.test.util.ChromeRenderTestRule;
+import org.chromium.chrome.test.util.browser.Features;
+import org.chromium.components.optimization_guide.OptimizationGuideDecision;
+import org.chromium.components.optimization_guide.proto.CommonTypesProto.Any;
+import org.chromium.components.page_info.PageInfoController;
+import org.chromium.components.page_info.PageInfoFeatures;
+import org.chromium.content_public.browser.test.util.TestThreadUtils;
+import org.chromium.ui.test.util.DisableAnimationsTestRule;
+import org.chromium.ui.test.util.UiRestriction;
+import org.chromium.url.GURL;
+
+import java.io.IOException;
+
+/**
+ * Tests for PageInfoStoreInfo view.
+ */
+@RunWith(ChromeJUnit4ClassRunner.class)
+@Features.EnableFeatures(PageInfoFeatures.PAGE_INFO_STORE_INFO_NAME)
+@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
+@Restriction({UiRestriction.RESTRICTION_TYPE_PHONE})
+@Batch(Batch.PER_CLASS)
+@DisabledTest(message = "crbug.com/1252308")
+public class PageInfoStoreInfoViewTest {
+    @ClassRule
+    public static final ChromeTabbedActivityTestRule sActivityTestRule =
+            new ChromeTabbedActivityTestRule();
+
+    @ClassRule
+    public static DisableAnimationsTestRule sDisableAnimationsTestRule =
+            new DisableAnimationsTestRule();
+
+    @Rule
+    public final BlankCTATabInitialStateRule mInitialStateRule =
+            new BlankCTATabInitialStateRule(sActivityTestRule, false);
+
+    @Rule
+    public JniMocker mMocker = new JniMocker();
+
+    @Rule
+    public ChromeRenderTestRule mRenderTestRule =
+            ChromeRenderTestRule.Builder.withPublicCorpus().build();
+
+    @Mock
+    private OptimizationGuideBridge.Natives mMockOptimizationGuideBridgeJni;
+
+    @Mock
+    private StoreInfoActionHandler mMockStoreInfoActionHandler;
+
+    private final MerchantTrustSignals mFakeMerchantTrustSigals =
+            MerchantTrustSignals.newBuilder()
+                    .setMerchantStarRating(4.5f)
+                    .setMerchantCountRating(100)
+                    .setMerchantDetailsPageUrl("http://dummy/url")
+                    .build();
+
+    private final Any mAnyMerchantTrustSignals =
+            Any.newBuilder()
+                    .setValue(ByteString.copyFrom(mFakeMerchantTrustSigals.toByteArray()))
+                    .build();
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+        mMocker.mock(OptimizationGuideBridgeJni.TEST_HOOKS, mMockOptimizationGuideBridgeJni);
+        doReturn(1L).when(mMockOptimizationGuideBridgeJni).init();
+    }
+
+    private void openPageInfo() {
+        ChromeActivity activity = sActivityTestRule.getActivity();
+        Tab tab = activity.getActivityTab();
+        TestThreadUtils.runOnUiThreadBlocking(() -> {
+            new ChromePageInfo(activity.getModalDialogManagerSupplier(), null,
+                    PageInfoController.OpenedFromSource.TOOLBAR, () -> mMockStoreInfoActionHandler)
+                    .show(tab, PageInfoController.NO_HIGHLIGHTED_PERMISSION);
+        });
+        onViewWaiting(allOf(withId(R.id.page_info_url_wrapper), isDisplayed()));
+    }
+
+    @Test
+    @MediumTest
+    public void testStoreInfoRowInvisibleWithoutData() {
+        mockOptimizationGuideResponse(
+                mMockOptimizationGuideBridgeJni, OptimizationGuideDecision.TRUE, null);
+        openPageInfo();
+        verifyStoreRowShowing(false);
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    public void testStoreInfoRowVisibleWithData() throws IOException {
+        mockOptimizationGuideResponse(mMockOptimizationGuideBridgeJni,
+                OptimizationGuideDecision.TRUE, mAnyMerchantTrustSignals);
+        openPageInfo();
+        verifyStoreRowShowing(true);
+        renderTestForStoreInfoRow("page_info_store_info_row");
+    }
+
+    @Test
+    @MediumTest
+    public void testStoreInfoRowClick() {
+        mockOptimizationGuideResponse(mMockOptimizationGuideBridgeJni,
+                OptimizationGuideDecision.TRUE, mAnyMerchantTrustSignals);
+        openPageInfo();
+        verifyStoreRowShowing(true);
+        onView(withId(PageInfoStoreInfoController.STORE_INFO_ROW_ID)).perform(click());
+        verify(mMockStoreInfoActionHandler, times(1))
+                .onStoreInfoClicked(any(MerchantTrustSignals.class));
+    }
+
+    private void mockOptimizationGuideResponse(OptimizationGuideBridge.Natives optimizationGuideJni,
+            @OptimizationGuideDecision int decision, Any metadata) {
+        doAnswer((Answer<Void>) invocation -> {
+            OptimizationGuideCallback callback =
+                    (OptimizationGuideCallback) invocation.getArguments()[3];
+            callback.onOptimizationGuideDecision(decision, metadata);
+            return null;
+        })
+                .when(optimizationGuideJni)
+                .canApplyOptimization(
+                        anyLong(), any(GURL.class), anyInt(), any(OptimizationGuideCallback.class));
+    }
+
+    private void verifyStoreRowShowing(boolean isVisible) {
+        onView(withId(PageInfoStoreInfoController.STORE_INFO_ROW_ID))
+                .check(matches(isVisible ? isDisplayed() : not(isDisplayed())));
+    }
+
+    private void renderTestForStoreInfoRow(String renderId) {
+        onView(withId(PageInfoStoreInfoController.STORE_INFO_ROW_ID))
+                .check((v, noMatchException) -> {
+                    if (noMatchException != null) throw noMatchException;
+                    try {
+                        mRenderTestRule.render(v, renderId);
+                    } catch (IOException e) {
+                        assert false : "Render test failed due to " + e;
+                    }
+                });
+    }
+}
\ No newline at end of file
diff --git a/chrome/browser/content_creation/notes/internal/android/BUILD.gn b/chrome/browser/content_creation/notes/internal/android/BUILD.gn
index 120eb535..99d530a 100644
--- a/chrome/browser/content_creation/notes/internal/android/BUILD.gn
+++ b/chrome/browser/content_creation/notes/internal/android/BUILD.gn
@@ -73,6 +73,7 @@
     "java/res/values-night/colors.xml",
     "java/res/values/colors.xml",
     "java/res/values/dimens.xml",
+    "java/res/values/ids.xml",
     "java/res/values/styles.xml",
   ]
 }
diff --git a/chrome/browser/content_creation/notes/internal/android/java/res/layout/carousel_item.xml b/chrome/browser/content_creation/notes/internal/android/java/res/layout/carousel_item.xml
index d96b66a..7af4245 100644
--- a/chrome/browser/content_creation/notes/internal/android/java/res/layout/carousel_item.xml
+++ b/chrome/browser/content_creation/notes/internal/android/java/res/layout/carousel_item.xml
@@ -7,6 +7,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     android:layout_width="@dimen/note_width"
     android:layout_height="280dp"
+    android:layout_marginBottom="24dp"
     android:orientation="vertical"
     android:layout_gravity="center_horizontal"
     android:layout_marginEnd="@dimen/note_side_padding"
diff --git a/chrome/browser/content_creation/notes/internal/android/java/res/layout/creation_dialog.xml b/chrome/browser/content_creation/notes/internal/android/java/res/layout/creation_dialog.xml
index 1a026eac..c3e5d08 100644
--- a/chrome/browser/content_creation/notes/internal/android/java/res/layout/creation_dialog.xml
+++ b/chrome/browser/content_creation/notes/internal/android/java/res/layout/creation_dialog.xml
@@ -6,6 +6,7 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/dialog_layout"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:background="@color/default_bg_color"
@@ -16,6 +17,7 @@
     <include layout="@layout/top_bar"/>
 
     <RelativeLayout
+        android:id="@+id/main_content"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:orientation="vertical"
diff --git a/chrome/browser/content_creation/notes/internal/android/java/res/values/dimens.xml b/chrome/browser/content_creation/notes/internal/android/java/res/values/dimens.xml
index 8048824d..287be691 100644
--- a/chrome/browser/content_creation/notes/internal/android/java/res/values/dimens.xml
+++ b/chrome/browser/content_creation/notes/internal/android/java/res/values/dimens.xml
@@ -13,4 +13,6 @@
 
     <dimen name="note_title_min_top_margin">64dp</dimen>
     <dimen name="note_title_top_margin_offset">640dp</dimen>
+
+    <dimen name="min_dialog_height">424dp</dimen>
 </resources>
diff --git a/chrome/browser/content_creation/notes/internal/android/java/res/values/ids.xml b/chrome/browser/content_creation/notes/internal/android/java/res/values/ids.xml
new file mode 100644
index 0000000..413a5e3
--- /dev/null
+++ b/chrome/browser/content_creation/notes/internal/android/java/res/values/ids.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2021 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file. -->
+
+<resources>
+    <item name="scrollview" type="id"/>
+</resources>
\ No newline at end of file
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
index b67a39f..cd95f294 100644
--- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
+++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationCoordinatorImpl.java
@@ -77,8 +77,8 @@
         mMediator = new NoteCreationMediator(mListModel, new GoogleFontService(mActivity),
                 noteService, new ImageService(imageFetcher));
 
-        String urlDomain =
-                UrlFormatter.formatUrlForDisplayOmitSchemeOmitTrivialSubdomains(mShareUrl);
+        String urlDomain = UrlFormatter.formatUrlForDisplayOmitSchemePathAndTrivialSubdomains(
+                new GURL(mShareUrl));
         mDialog = new NoteCreationDialog();
         mDialog.initDialog(this::onViewCreated, urlDomain, title, selectedText,
                 noteService.isPublishAvailable(), this::executeAction);
diff --git a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java
index 37361fe..8d83c56 100644
--- a/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java
+++ b/chrome/browser/content_creation/notes/internal/android/java/src/org/chromium/chrome/browser/content_creation/notes/NoteCreationDialog.java
@@ -14,6 +14,9 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.Button;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RelativeLayout;
+import android.widget.ScrollView;
 import android.widget.TextView;
 
 import androidx.appcompat.app.AlertDialog;
@@ -83,6 +86,7 @@
         builder.setView(mContentView);
 
         setTitleTopMargin();
+        addOrRemoveScrollView();
 
         if (mIsPublishAvailable) {
             Button publishButton = (Button) mContentView.findViewById(R.id.publish);
@@ -109,6 +113,9 @@
         // Title top margin depends on screen orientation.
         setTitleTopMargin();
 
+        // Add or remove scroll view as needed.
+        addOrRemoveScrollView();
+
         // Force recycler view to redraw to recalculate the left/right paddings for first/last
         // items.
         RecyclerView noteCarousel = mContentView.findViewById(R.id.note_carousel);
@@ -333,4 +340,43 @@
         titleView.setLayoutParams(params);
         titleView.requestLayout();
     }
+
+    private void addScrollView() {
+        assert mContentView.findViewById(R.id.scrollview) == null;
+
+        ScrollView scrollView = new ScrollView(getActivity());
+        scrollView.setLayoutParams(new LinearLayout.LayoutParams(
+                ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+        scrollView.setId(R.id.scrollview);
+
+        LinearLayout dialogLayout = mContentView.findViewById(R.id.dialog_layout);
+        RelativeLayout mainContent = dialogLayout.findViewById(R.id.main_content);
+        dialogLayout.removeView(mainContent);
+        scrollView.addView(mainContent);
+        dialogLayout.addView(scrollView);
+    }
+
+    private void removeScrollView() {
+        assert mContentView.findViewById(R.id.scrollview) != null;
+
+        LinearLayout dialogLayout = mContentView.findViewById(R.id.dialog_layout);
+        RelativeLayout mainContent = dialogLayout.findViewById(R.id.main_content);
+        ScrollView scrollView = dialogLayout.findViewById(R.id.scrollview);
+        scrollView.removeView(mainContent);
+        dialogLayout.removeView(scrollView);
+        dialogLayout.addView(mainContent);
+    }
+
+    private void addOrRemoveScrollView() {
+        int screenHeight = getActivity().getResources().getDisplayMetrics().heightPixels;
+        int dialogHeight =
+                (int) getActivity().getResources().getDimension(R.dimen.min_dialog_height);
+        if (dialogHeight < screenHeight && mContentView.findViewById(R.id.scrollview) != null) {
+            removeScrollView();
+        }
+
+        if (dialogHeight > screenHeight && mContentView.findViewById(R.id.scrollview) == null) {
+            addScrollView();
+        }
+    }
 }
\ No newline at end of file
diff --git a/chrome/browser/download/internal/android/java/res/layout/download_home_tabs.xml b/chrome/browser/download/internal/android/java/res/layout/download_home_tabs.xml
index 292c1ed..4265abef 100644
--- a/chrome/browser/download/internal/android/java/res/layout/download_home_tabs.xml
+++ b/chrome/browser/download/internal/android/java/res/layout/download_home_tabs.xml
@@ -4,7 +4,9 @@
      found in the LICENSE file.
 -->
 
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:orientation="vertical">
@@ -13,6 +15,8 @@
         android:id="@+id/tabs"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        app:tabPaddingStart="5dp"
+        app:tabPaddingEnd="5dp"
         style="@style/TabLayoutStyle" >
 
         <com.google.android.material.tabs.TabItem
diff --git a/chrome/browser/extensions/api/module/module.cc b/chrome/browser/extensions/api/module/module.cc
index 18c0949..fc82671 100644
--- a/chrome/browser/extensions/api/module/module.cc
+++ b/chrome/browser/extensions/api/module/module.cc
@@ -14,30 +14,11 @@
 #include "extensions/browser/extension_prefs.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extension_util.h"
+#include "extensions/common/constants.h"
 #include "extensions/common/manifest_url_handlers.h"
 
 namespace extensions {
 
-namespace extension {
-
-namespace {
-
-// A preference for storing the extension's update URL data. If not empty, the
-// the ExtensionUpdater will append a ap= parameter to the URL when checking if
-// a new version of the extension is available.
-const char kUpdateURLData[] = "update_url_data";
-
-}  // namespace
-
-std::string GetUpdateURLData(const ExtensionPrefs* prefs,
-                             const std::string& extension_id) {
-  std::string data;
-  prefs->ReadPrefAsString(extension_id, kUpdateURLData, &data);
-  return data;
-}
-
-}  // namespace extension
-
 ExtensionFunction::ResponseAction ExtensionSetUpdateUrlDataFunction::Run() {
   EXTENSION_FUNCTION_VALIDATE(args().size() >= 1);
   EXTENSION_FUNCTION_VALIDATE(args()[0].is_string());
@@ -50,7 +31,7 @@
   }
 
   ExtensionPrefs::Get(browser_context())
-      ->UpdateExtensionPref(extension_id(), extension::kUpdateURLData,
+      ->UpdateExtensionPref(extension_id(), kUpdateURLData,
                             std::make_unique<base::Value>(data));
   return RespondNow(NoArguments());
 }
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
index 5eb5538..d96fecd25 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.cc
@@ -787,7 +787,7 @@
 
 void SafeBrowsingPrivateEventRouter::OnPasswordBreach(
     const std::string& trigger,
-    const std::vector<std::pair<GURL, std::string>>& identities) {
+    const std::vector<std::pair<GURL, std::u16string>>& identities) {
   absl::optional<enterprise_connectors::ReportingSettings> settings =
       GetReportingSettings();
   if (!settings.has_value() ||
@@ -798,7 +798,7 @@
   base::Value event(base::Value::Type::DICTIONARY);
   std::vector<base::Value> identities_list;
   event.SetStringKey(kKeyTrigger, trigger);
-  for (const std::pair<GURL, std::string>& i : identities) {
+  for (const std::pair<GURL, std::u16string>& i : identities) {
     base::Value identity(base::Value::Type::DICTIONARY);
     identity.SetStringKey(kKeyPasswordBreachIdentitiesUrl, i.first.spec());
     identity.SetStringKey(kKeyPasswordBreachIdentitiesUsername, i.second);
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h
index 0bdf26e7..da6b75d4 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h
@@ -233,7 +233,7 @@
 
   void OnPasswordBreach(
       const std::string& trigger,
-      const std::vector<std::pair<GURL, std::string>>& identities);
+      const std::vector<std::pair<GURL, std::u16string>>& identities);
 
   // Returns true if enterprise real-time reporting should be initialized,
   // checking both the feature flag. This function is public so that it can
diff --git a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc
index 177fcf2..fb8943d 100644
--- a/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc
+++ b/chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_unittest.cc
@@ -220,7 +220,7 @@
 
   void TriggerOnPasswordBreachEvent(
       const std::string& trigger,
-      const std::vector<std::pair<GURL, std::string>>& identities) {
+      const std::vector<std::pair<GURL, std::u16string>>& identities) {
     SafeBrowsingPrivateEventRouterFactory::GetForProfile(profile_)
         ->OnPasswordBreach(trigger, identities);
   }
@@ -788,16 +788,16 @@
   validator.ExpectPasswordBreachEvent(
       "SAFETY_CHECK",
       {
-          {"https://first.example.com/", "first_user_name"},
-          {"https://second.example.com/", "second_user_name"},
+          {"https://first.example.com/", u"first_user_name"},
+          {"https://second.example.com/", u"second_user_name"},
       },
       profile_->GetProfileUserName());
 
   TriggerOnPasswordBreachEvent(
       "SAFETY_CHECK",
       {
-          {GURL("https://first.example.com"), "first_user_name"},
-          {GURL("https://second.example.com"), "second_user_name"},
+          {GURL("https://first.example.com"), u"first_user_name"},
+          {GURL("https://second.example.com"), u"second_user_name"},
       });
 }
 
diff --git a/chrome/browser/extensions/updater/extension_updater.cc b/chrome/browser/extensions/updater/extension_updater.cc
index 9f45c73..2430448 100644
--- a/chrome/browser/extensions/updater/extension_updater.cc
+++ b/chrome/browser/extensions/updater/extension_updater.cc
@@ -21,7 +21,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_split.h"
 #include "chrome/browser/chrome_notification_types.h"
-#include "chrome/browser/extensions/api/module/module.h"
 #include "chrome/browser/extensions/crx_installer.h"
 #include "chrome/browser/extensions/extension_management.h"
 #include "chrome/browser/extensions/extension_service.h"
@@ -100,6 +99,13 @@
   return SanitizeDays((base::Time::Now() - last_active_ping_day).InDays());
 }
 
+std::string GetUpdateURLData(const extensions::ExtensionPrefs* prefs,
+                             const std::string& extension_id) {
+  std::string data;
+  prefs->ReadPrefAsString(extension_id, extensions::kUpdateURLData, &data);
+  return data;
+}
+
 }  // namespace
 
 namespace extensions {
@@ -333,8 +339,7 @@
   // communicate to the gallery update servers.
   std::string update_url_data;
   if (!ManifestURL::UpdatesFromGallery(&extension))
-    update_url_data =
-        extension::GetUpdateURLData(extension_prefs_, extension.id());
+    update_url_data = GetUpdateURLData(extension_prefs_, extension.id());
 
   return downloader_->AddPendingExtensionWithVersion(
       extension.id(), update_url, extension.location(),
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index 412a47c..2d6bd563 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -263,6 +263,12 @@
     "expiry_milestone": 95
   },
   {
+    "name": "arc-usb-device-attach-to-vm-experiment",
+    "owners": [ "lgcheng" ],
+    // Used on ChromeOS to temperorily attach unclaimed USB device to ARCVM
+    "expiry_milestone": 98
+  },
+  {
     "name": "arc-use-high-memory-dalvik-profile",
     "owners": [ "khmel" ],
     "expiry_milestone": 92
@@ -785,7 +791,7 @@
   {
     "name": "composite-after-paint",
     "owners": [ "pdr", "wangxianzhu" ],
-    "expiry_milestone": 95
+    "expiry_milestone": 97
   },
   {
     "name": "compositor-threaded-scrollbar-scrolling",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 6dd60b2..20d357f 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4099,6 +4099,11 @@
     "Enable ARC real time vcpu on a device with 3+ logical cores online to "
     "reduce media playback glitch.";
 
+const char kArcUsbDeviceDefaultAttachToVmName[] =
+    "Attach unclaimed USB devices to ARCVM";
+const char kArcUsbDeviceDefaultAttachToVmDescription[] =
+    "When ARCVM is enabled, always attach unclaimed USB devices to ARCVM";
+
 const char kArcUseHighMemoryDalvikProfileName[] =
     "Enable ARC high-memory dalvik profile";
 const char kArcUseHighMemoryDalvikProfileDesc[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a3263e8e..08623a0 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2340,6 +2340,9 @@
 extern const char kArcRtVcpuQuadCoreName[];
 extern const char kArcRtVcpuQuadCoreDesc[];
 
+extern const char kArcUsbDeviceDefaultAttachToVmName[];
+extern const char kArcUsbDeviceDefaultAttachToVmDescription[];
+
 extern const char kArcUseHighMemoryDalvikProfileName[];
 extern const char kArcUseHighMemoryDalvikProfileDesc[];
 
diff --git a/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h b/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h
index 6cc08a5..d3281bf 100644
--- a/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h
+++ b/chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h
@@ -33,6 +33,11 @@
   // the app.
   void InitWebKioskSession(Browser* browser);
 
+  // Get app session object for testing purpose only.
+  chromeos::AppSession* GetAppSessionForTesting() const {
+    return app_session_.get();
+  }
+
  protected:
   // Tell the ash-chrome to end the kiosk session and return the current user
   // to the login screen by calling the API provided by
diff --git a/chrome/browser/lacros/browser_service_lacros_browsertest.cc b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
index 8c10b52..0c355c7 100644
--- a/chrome/browser/lacros/browser_service_lacros_browsertest.cc
+++ b/chrome/browser/lacros/browser_service_lacros_browsertest.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "base/test/bind.h"
+#include "chrome/browser/chromeos/app_mode/app_session.h"
+#include "chrome/browser/lacros/app_mode/kiosk_session_service_lacros.h"
 #include "chrome/browser/lacros/browser_service_lacros.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/browser/ui/browser_window.h"
@@ -51,6 +53,17 @@
           EXPECT_EQ(result, CreationResult::kSuccess);
         }));
     EXPECT_TRUE(use_callback);
+
+    // Verify `AppSession` object is created when `NewFullscreenWindow` is
+    // called in the Web Kiosk session. Then, disable the `AttemptUserExit`
+    // method to do nothing.
+    if (chromeos::LacrosService::Get()->init_params()->session_type ==
+        SessionType::kWebKioskSession) {
+      chromeos::AppSession* app_session =
+          KioskSessionServiceLacros::Get()->GetAppSessionForTesting();
+      EXPECT_TRUE(app_session);
+      app_session->SetAttemptUserExitForTesting(base::DoNothing());
+    }
   }
 
   void CreateNewWindow() {
diff --git a/chrome/browser/lens/region_search/BUILD.gn b/chrome/browser/lens/region_search/BUILD.gn
index 9330d65..320d405 100644
--- a/chrome/browser/lens/region_search/BUILD.gn
+++ b/chrome/browser/lens/region_search/BUILD.gn
@@ -3,9 +3,7 @@
 # found in the LICENSE file.
 
 # Contained Lens dependencies are currently for desktop platforms only
-# TODO(crbug/1229334): Add Mac support for Lens Region Search feature.
-assert(is_chromeos || is_linux || is_win,
-       "Lens Region Search is for desktop platforms only, excluding Mac")
+assert(!is_android, "Lens Region Search is for desktop platforms only")
 
 static_library("region_search") {
   sources = [
diff --git a/chrome/browser/media/webrtc/media_stream_permission_browsertest.cc b/chrome/browser/media/webrtc/media_stream_permission_browsertest.cc
index 51456d2..5e38d7a3 100644
--- a/chrome/browser/media/webrtc/media_stream_permission_browsertest.cc
+++ b/chrome/browser/media/webrtc/media_stream_permission_browsertest.cc
@@ -126,36 +126,38 @@
 
 // Actual tests ---------------------------------------------------------------
 
-IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest, TestAllowingUserMedia) {
+// Entire test suite is flaky: https://crbug.com/1252385
+IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
+                       DISABLED_TestAllowingUserMedia) {
   content::WebContents* tab_contents = LoadTestPageInTab();
   EXPECT_TRUE(GetUserMediaAndAccept(tab_contents));
 }
 
-IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest, TestDenyingUserMedia) {
+// Entire test suite is flaky: https://crbug.com/1252385
+IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
+                       DISABLED_TestDenyingUserMedia) {
   content::WebContents* tab_contents = LoadTestPageInTab();
   GetUserMediaAndDeny(tab_contents);
 }
 
-IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest, TestDismissingRequest) {
+// Entire test suite is flaky: https://crbug.com/1252385
+IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
+                       DISABLED_TestDismissingRequest) {
   content::WebContents* tab_contents = LoadTestPageInTab();
   GetUserMediaAndDismiss(tab_contents);
 }
 
 // TODO(crbug.com/1251470): Fix the issue on Lacros and enable the test.
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#define MAYBE_TestDenyingUserMediaIncognito \
-  DISABLED_TestDenyingUserMediaIncognito
-#else
-#define MAYBE_TestDenyingUserMediaIncognito TestDenyingUserMediaIncognito
-#endif
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       MAYBE_TestDenyingUserMediaIncognito) {
+                       DISABLED_TestDenyingUserMediaIncognito) {
   content::WebContents* tab_contents = LoadTestPageInIncognitoTab();
   GetUserMediaAndDeny(tab_contents);
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       TestSecureOriginDenyIsSticky) {
+                       DISABLED_TestSecureOriginDenyIsSticky) {
   content::WebContents* tab_contents = LoadTestPageInTab();
   EXPECT_TRUE(network::IsUrlPotentiallyTrustworthy(
       tab_contents->GetLastCommittedURL()));
@@ -164,8 +166,9 @@
   GetUserMediaAndExpectAutoDenyWithoutPrompt(tab_contents);
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       TestSecureOriginAcceptIsSticky) {
+                       DISABLED_TestSecureOriginAcceptIsSticky) {
   content::WebContents* tab_contents = LoadTestPageInTab();
   EXPECT_TRUE(network::IsUrlPotentiallyTrustworthy(
       tab_contents->GetLastCommittedURL()));
@@ -174,15 +177,18 @@
   GetUserMediaAndExpectAutoAcceptWithoutPrompt(tab_contents);
 }
 
-IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest, TestDismissIsNotSticky) {
+// Entire test suite is flaky: https://crbug.com/1252385
+IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
+                       DISABLED_TestDismissIsNotSticky) {
   content::WebContents* tab_contents = LoadTestPageInTab();
 
   GetUserMediaAndDismiss(tab_contents);
   GetUserMediaAndDismiss(tab_contents);
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       TestDenyingThenClearingStickyException) {
+                       DISABLED_TestDenyingThenClearingStickyException) {
   content::WebContents* tab_contents = LoadTestPageInTab();
 
   GetUserMediaAndDeny(tab_contents);
@@ -198,8 +204,9 @@
   GetUserMediaAndDeny(tab_contents);
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       DenyingMicDoesNotCauseStickyDenyForCameras) {
+                       DISABLED_DenyingMicDoesNotCauseStickyDenyForCameras) {
   content::WebContents* tab_contents = LoadTestPageInTab();
 
   GetUserMediaWithSpecificConstraintsAndDeny(tab_contents,
@@ -208,8 +215,9 @@
       tab_contents, kVideoOnlyCallConstraints));
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       DenyingCameraDoesNotCauseStickyDenyForMics) {
+                       DISABLED_DenyingCameraDoesNotCauseStickyDenyForMics) {
   content::WebContents* tab_contents = LoadTestPageInTab();
 
   GetUserMediaWithSpecificConstraintsAndDeny(tab_contents,
@@ -221,29 +229,33 @@
 // TODO(crbug.com/1204412) Disabled because the original test was only passing
 // due to a bug in the code. Now that the bug is fixed, the test is not passing
 // anymore.
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       DenyingCameraPermissionStopsAVStream) {
+                       DISABLED_DenyingCameraPermissionStopsAVStream) {
   TestPermissionDenialEffectOnStream(kAudioVideoCallConstraints,
                                      ContentSettingsType::MEDIASTREAM_CAMERA,
                                      true /* should_video_stop */);
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       DenyingMicPermissionStopsAVStream) {
+                       DISABLED_DenyingMicPermissionStopsAVStream) {
   TestPermissionDenialEffectOnStream(kAudioVideoCallConstraints,
                                      ContentSettingsType::MEDIASTREAM_MIC,
                                      true /* should_video_stop */);
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       DenyingCameraPermissionStopsVideoOnlyStream) {
+                       DISABLED_DenyingCameraPermissionStopsVideoOnlyStream) {
   TestPermissionDenialEffectOnStream(kVideoOnlyCallConstraints,
                                      ContentSettingsType::MEDIASTREAM_CAMERA,
                                      true /* should_video_stop */);
 }
 
+// Entire test suite is flaky: https://crbug.com/1252385
 IN_PROC_BROWSER_TEST_F(MediaStreamPermissionTest,
-                       DenyingMicPermissionDoesntStopVideoOnlyStream) {
+                       DISABLED_DenyingMicPermissionDoesntStopVideoOnlyStream) {
   TestPermissionDenialEffectOnStream(kVideoOnlyCallConstraints,
                                      ContentSettingsType::MEDIASTREAM_MIC,
                                      false /* should_video_stop */);
diff --git a/chrome/browser/metrics/chrome_feature_list_creator.cc b/chrome/browser/metrics/chrome_feature_list_creator.cc
index 10286321..82e9b679a 100644
--- a/chrome/browser/metrics/chrome_feature_list_creator.cc
+++ b/chrome/browser/metrics/chrome_feature_list_creator.cc
@@ -7,7 +7,6 @@
 #include <set>
 #include <vector>
 
-#include "base/base_switches.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -169,7 +168,8 @@
   browser_field_trials_ =
       std::make_unique<ChromeBrowserFieldTrials>(local_state_.get());
 
-  metrics_services_manager_->InstantiateFieldTrialList();
+  metrics_services_manager_->InstantiateFieldTrialList(
+      cc::switches::kEnableGpuBenchmarking);
   auto feature_list = std::make_unique<base::FeatureList>();
 
   // Associate parameters chosen in about:flags and create trial/group for them.
@@ -181,8 +181,7 @@
   variations::VariationsService* variations_service =
       metrics_services_manager_->GetVariationsService();
   variations_service->SetupFieldTrials(
-      cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
-      switches::kDisableFeatures, variation_ids,
+      variation_ids,
       content::GetSwitchDependentFeatureOverrides(
           *base::CommandLine::ForCurrentProcess()),
       std::move(feature_list), browser_field_trials_.get());
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc
index ee89f1b..ab1ee09 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.cc
+++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -97,7 +97,6 @@
 #include "content/public/browser/ssl_status.h"
 #include "content/public/browser/storage_partition.h"
 #include "content/public/browser/web_contents.h"
-#include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "extensions/buildflags/buildflags.h"
 #include "google_apis/gaia/gaia_urls.h"
@@ -118,7 +117,6 @@
 #endif
 
 #if defined(OS_ANDROID)
-#include "base/feature_list.h"
 #include "chrome/browser/android/tab_android.h"
 #include "chrome/browser/autofill/manual_filling_controller.h"
 #include "chrome/browser/password_manager/android/account_chooser_dialog_android.h"
@@ -183,6 +181,10 @@
 
 namespace {
 
+#if !defined(OS_ANDROID)
+static const char kPasswordBreachEntryTrigger[] = "PASSWORD_ENTRY";
+#endif
+
 const syncer::SyncService* GetSyncService(Profile* profile) {
   if (SyncServiceFactory::HasSyncService(profile))
     return SyncServiceFactory::GetForProfile(profile);
@@ -886,6 +888,24 @@
   // is enabled by the admin.
   router->OnLoginEvent(url, is_federated, federated_origin);
 }
+
+void ChromePasswordManagerClient::MaybeReportEnterprisePasswordBreachEvent(
+    const std::vector<std::pair<GURL, std::u16string>>& identities) const {
+  if (!base::FeatureList::IsEnabled(
+          policy::features::kPasswordBreachEventReporting)) {
+    return;
+  }
+
+  extensions::SafeBrowsingPrivateEventRouter* router =
+      extensions::SafeBrowsingPrivateEventRouterFactory::GetForProfile(
+          profile_);
+  if (!router)
+    return;
+
+  // The router is responsible for checking if the reporting of this event type
+  // is enabled by the admin.
+  router->OnPasswordBreach(kPasswordBreachEntryTrigger, identities);
+}
 #endif
 
 ukm::SourceId ChromePasswordManagerClient::GetUkmSourceId() {
@@ -961,8 +981,9 @@
   return FieldInfoManagerFactory::GetForBrowserContext(profile_);
 }
 
-bool ChromePasswordManagerClient::IsWebAuthnAutofillEnabled() const {
-  return base::FeatureList::IsEnabled(features::kWebAuthConditionalUI);
+password_manager::WebAuthnCredentialsDelegate*
+ChromePasswordManagerClient::GetWebAuthnCredentialsDelegate() {
+  return &webauthn_credentials_delegate_;
 }
 
 void ChromePasswordManagerClient::AutomaticGenerationAvailable(
@@ -1201,6 +1222,7 @@
       httpauth_manager_(this),
       password_reuse_detection_manager_(this),
       driver_factory_(nullptr),
+      webauthn_credentials_delegate_(this),
       content_credential_manager_(this),
       password_generation_driver_receivers_(web_contents, this),
       observer_(nullptr),
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index c162fe4..2b72935 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -15,6 +15,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
+#include "chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h"
 #include "components/autofill/content/common/mojom/autofill_driver.mojom-forward.h"
 #include "components/autofill/core/common/password_generation_util.h"
 #include "components/autofill/core/common/unique_ids.h"
@@ -220,12 +221,16 @@
       bool password_field_exists) override;
 
   void LogPasswordReuseDetectedEvent() override;
+
+  // Reporting these events is only supported on desktop platforms.
 #if !defined(OS_ANDROID)
-  // Reporting this event is only supported on desktop platforms.
   void MaybeReportEnterpriseLoginEvent(
       const GURL& url,
       bool is_federated,
       const url::Origin& federated_origin) const override;
+  void MaybeReportEnterprisePasswordBreachEvent(
+      const std::vector<std::pair<GURL, std::u16string>>& identities)
+      const override;
 #endif
 
   ukm::SourceId GetUkmSourceId() override;
@@ -243,7 +248,8 @@
   bool IsIsolationForPasswordSitesEnabled() const override;
   bool IsNewTabPage() const override;
   password_manager::FieldInfoManager* GetFieldInfoManager() const override;
-  bool IsWebAuthnAutofillEnabled() const override;
+  password_manager::WebAuthnCredentialsDelegate*
+  GetWebAuthnCredentialsDelegate() override;
 
   // autofill::mojom::PasswordGenerationDriver overrides.
   void AutomaticGenerationAvailable(
@@ -390,6 +396,8 @@
 
   password_manager::ContentPasswordManagerDriverFactory* driver_factory_;
 
+  ChromeWebAuthnCredentialsDelegate webauthn_credentials_delegate_;
+
   // As a mojo service, will be registered into service registry
   // of the main frame host by ChromeContentBrowserClient
   // once main frame host was created.
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc
new file mode 100644
index 0000000..98e5e62
--- /dev/null
+++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.cc
@@ -0,0 +1,73 @@
+// Copyright 2021 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/password_manager/chrome_webauthn_credentials_delegate.h"
+
+#include "base/feature_list.h"
+#include "build/build_config.h"
+#include "chrome/browser/password_manager/chrome_password_manager_client.h"
+#include "content/public/common/content_features.h"
+
+#if !defined(OS_ANDROID)
+#include "chrome/browser/webauthn/authenticator_request_scheduler.h"
+#include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h"
+#endif  // !defined(OS_ANDROID)
+
+ChromeWebAuthnCredentialsDelegate::ChromeWebAuthnCredentialsDelegate(
+    ChromePasswordManagerClient* client)
+    : client_(client) {}
+
+bool ChromeWebAuthnCredentialsDelegate::IsWebAuthnAutofillEnabled() const {
+  return base::FeatureList::IsEnabled(features::kWebAuthConditionalUI);
+}
+
+void ChromeWebAuthnCredentialsDelegate::SelectWebAuthnCredential(
+    std::string backend_id) {
+#if !defined(OS_ANDROID)
+  ChromeAuthenticatorRequestDelegate* authenticator_delegate =
+      AuthenticatorRequestScheduler::GetRequestDelegate(
+          client_->web_contents());
+  if (!authenticator_delegate) {
+    return;
+  }
+  authenticator_delegate->dialog_model()->OnAccountPreselected(
+      std::vector<uint8_t>(backend_id.begin(), backend_id.end()));
+#endif  // !defined(OS_ANDROID)
+}
+
+std::vector<autofill::Suggestion>
+ChromeWebAuthnCredentialsDelegate::GetWebAuthnSuggestions() const {
+#if defined(OS_ANDROID)
+  return {};
+#else
+  ChromeAuthenticatorRequestDelegate* authenticator_delegate =
+      AuthenticatorRequestScheduler::GetRequestDelegate(
+          client_->web_contents());
+  if (!authenticator_delegate) {
+    return {};
+  }
+  std::vector<autofill::Suggestion> suggestions;
+  for (const auto& credential :
+       authenticator_delegate->dialog_model()->users()) {
+    std::u16string name;
+    if (credential.display_name && !credential.display_name->empty()) {
+      name = base::UTF8ToUTF16(*credential.display_name);
+    } else {
+      // TODO(crbug.com/1179014): go through UX review, choose a string, and
+      // i18n it.
+      name = u"Unknown account";
+    }
+    autofill::Suggestion suggestion(std::move(name));
+    if (credential.name) {
+      suggestion.label = base::UTF8ToUTF16(*credential.name);
+    }
+    suggestion.icon = "fingerprint";
+    suggestion.frontend_id = autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL;
+    suggestion.backend_id =
+        std::string(credential.id.begin(), credential.id.end());
+    suggestions.push_back(std::move(suggestion));
+  }
+  return suggestions;
+#endif
+}
diff --git a/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h
new file mode 100644
index 0000000..08f0d5e9
--- /dev/null
+++ b/chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h
@@ -0,0 +1,35 @@
+// Copyright 2021 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_PASSWORD_MANAGER_CHROME_WEBAUTHN_CREDENTIALS_DELEGATE_H_
+#define CHROME_BROWSER_PASSWORD_MANAGER_CHROME_WEBAUTHN_CREDENTIALS_DELEGATE_H_
+
+#include "components/password_manager/core/browser/webauthn_credentials_delegate.h"
+
+class ChromePasswordManagerClient;
+
+// Chrome implementation of WebAuthnCredentialsDelegate.
+class ChromeWebAuthnCredentialsDelegate
+    : public password_manager::WebAuthnCredentialsDelegate {
+ public:
+  explicit ChromeWebAuthnCredentialsDelegate(
+      ChromePasswordManagerClient* client);
+  ~ChromeWebAuthnCredentialsDelegate() override = default;
+  ChromeWebAuthnCredentialsDelegate(const ChromeWebAuthnCredentialsDelegate&) =
+      delete;
+  ChromeWebAuthnCredentialsDelegate operator=(
+      const ChromeWebAuthnCredentialsDelegate&) = delete;
+  ChromeWebAuthnCredentialsDelegate(ChromeWebAuthnCredentialsDelegate&&) =
+      delete;
+
+  // password_manager::WebAuthnCredentialsDelegate:
+  bool IsWebAuthnAutofillEnabled() const override;
+  void SelectWebAuthnCredential(std::string backend_id) override;
+  std::vector<autofill::Suggestion> GetWebAuthnSuggestions() const override;
+
+ protected:
+  ChromePasswordManagerClient* const client_;
+};
+
+#endif  // CHROME_BROWSER_PASSWORD_MANAGER_CHROME_WEBAUTHN_CREDENTIALS_DELEGATE_H_
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
index ef1c283..8263f0fe 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -224,15 +224,11 @@
 #endif
 
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#include "chrome/browser/lens/region_search/lens_region_search_controller.h"
 #include "chrome/grit/theme_resources.h"
 #include "ui/base/resource/resource_bundle.h"
 #endif
 
-#if (defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX)) && \
-    BUILDFLAG(GOOGLE_CHROME_BRANDING)
-#include "chrome/browser/lens/region_search/lens_region_search_controller.h"
-#endif
-
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
 #include "ash/public/cpp/clipboard_history_controller.h"
@@ -617,7 +613,6 @@
 }
 
 #if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS) ||    \
-    (defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX)) && \
         BUILDFLAG(GOOGLE_CHROME_BRANDING)
 ui::MenuSourceType GetMenuSourceType(int event_flags) {
   if (event_flags & ui::EF_LEFT_MOUSE_BUTTON)
@@ -1372,8 +1367,10 @@
                                      : share::ShareSubmenuModel::Context::LINK;
       GURL url =
           params_.has_image_contents ? params_.src_url : params_.link_url;
+      std::u16string text =
+          params_.has_image_contents ? u"" : params_.link_text;
       share_submenu_model_ = std::make_unique<share::ShareSubmenuModel>(
-          GetBrowser(), CreateDataEndpoint(true), context, url);
+          GetBrowser(), CreateDataEndpoint(true), context, url, text);
       if (share_submenu_model_->GetItemCount() > 0) {
         menu_model_.AddSubMenuWithStringId(IDC_CONTENT_CONTEXT_SHARING_SUBMENU,
                                            IDS_SHARE_MENU_TITLE,
@@ -1541,7 +1538,7 @@
   if (ShouldUseShareMenu() && !share_submenu_model_) {
     share_submenu_model_ = std::make_unique<share::ShareSubmenuModel>(
         GetBrowser(), CreateDataEndpoint(true),
-        share::ShareSubmenuModel::Context::IMAGE, params_.src_url);
+        share::ShareSubmenuModel::Context::IMAGE, params_.src_url, u"");
     if (share_submenu_model_->GetItemCount() > 0) {
       menu_model_.AddSubMenuWithStringId(IDC_CONTENT_CONTEXT_SHARING_SUBMENU,
                                          IDS_SHARE_MENU_TITLE,
@@ -1662,8 +1659,7 @@
                                   IDS_CONTENT_CONTEXT_SAVEPAGEAS);
   menu_model_.AddItemWithStringId(IDC_PRINT, IDS_CONTENT_CONTEXT_PRINT);
   AppendMediaRouterItem();
-#if (defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX)) && \
-    BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (IsLensRegionSearchEnabled()) {
     AppendLensRegionSearchItem();
   }
@@ -1673,7 +1669,8 @@
     menu_model_.AddSeparator(ui::NORMAL_SEPARATOR);
     share_submenu_model_ = std::make_unique<share::ShareSubmenuModel>(
         GetBrowser(), CreateDataEndpoint(true),
-        share::ShareSubmenuModel::Context::PAGE, params_.page_url);
+        share::ShareSubmenuModel::Context::PAGE, params_.page_url,
+        source_web_contents_->GetTitle());
     if (share_submenu_model_->GetItemCount() > 0) {
       menu_model_.AddSubMenuWithStringId(IDC_CONTENT_CONTEXT_SHARING_SUBMENU,
                                          IDS_SHARE_MENU_TITLE,
@@ -3319,8 +3316,7 @@
 }
 
 void RenderViewContextMenu::ExecLensRegionSearch(int event_flags) {
-#if (defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX)) && \
-    BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   if (!lens_region_search_controller_)
     lens_region_search_controller_ =
         std::make_unique<lens::LensRegionSearchController>(source_web_contents_,
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.h b/chrome/browser/renderer_context_menu/render_view_context_menu.h
index 227525c..304bdfd 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu.h
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu.h
@@ -32,8 +32,7 @@
 #include "ui/base/window_open_disposition.h"
 #include "ui/gfx/geometry/vector2d.h"
 
-#if (defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX)) && \
-    BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #include "chrome/browser/lens/region_search/lens_region_search_controller.h"
 #endif
 
@@ -367,8 +366,7 @@
   // The system app (if any) associated with the WebContents we're in.
   const web_app::SystemWebAppDelegate* system_app_ = nullptr;
 
-#if (defined(OS_WIN) || defined(OS_CHROMEOS) || defined(OS_LINUX)) && \
-    BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
   // Controller for Lens Region Search feature. This controller will be
   // destroyed as soon as the RenderViewContextMenu object is destroyed. The
   // RenderViewContextMenu is reset every time it is shown, but persists between
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
index f33720bb8..516bd0fd 100644
--- a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
+++ b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
@@ -709,9 +709,7 @@
   EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_SHOWALLSAVEDPASSWORDS));
 }
 
-// TODO(crbug/1229334): Add Mac support for Lens Region Search feature.
-#if (defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)) && \
-    BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
 // Verify that the Lens Region Search menu item is displayed when the feature
 // is enabled.
 TEST_F(RenderViewContextMenuPrefsTest, LensRegionSearch) {
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/commands.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/commands.js
index a5df20d..93f11a6 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/commands.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/commands.js
@@ -25,15 +25,6 @@
      * @private {!Map<Command.Action, ActionInfo>}
      */
     this.commandMap_ = new Map();
-
-    chrome.accessibilityPrivate.isFeatureEnabled(
-        chrome.accessibilityPrivate.AccessibilityFeature.DICTATION_COMMANDS,
-        (result) => {
-          this.commandsFeatureEnabled_ = result;
-          if (this.commandsFeatureEnabled_) {
-            this.initializeCommandMap_();
-          }
-        });
   }
 
   /**
@@ -61,11 +52,24 @@
   }
 
   /**
-   * Pre-work to parse commands. Gets translated command strings and generates
-   * a map of commands to regular expressions that would match them.
-   * @private
+   * Gets the description of a command.
+   * @param {Command} command
+   * @return {string}
    */
-  initializeCommandMap_() {
+  getCommandString(command) {
+    if (command.isTextInput()) {
+      return '';
+    }
+    return this.commandMap_.get(command.action_).commandString;
+  }
+
+  /**
+   * Enables commands. Does pre-work to parse commands: gets translated command
+   * strings and generates a map of commands to regular expressions that would
+   * match them.
+   */
+  setCommandsEnabled() {
+    this.commandsFeatureEnabled_ = true;
     for (const key in Command.Action) {
       const actionId = Command.Action[key];
       let messageId;
@@ -196,6 +200,7 @@
 
   /**
    * Executes the command.
+   * @return {boolean} Whether execution was successful.
    */
   execute() {
     // Commands using keyboard shortcuts.
@@ -248,7 +253,9 @@
             'Cannot execute action ' +
             Object.keys(Command.Action)
                 .find(key => Command.Action[key] === this.action_));
+        return false;
     }
+    return true;
   }
 }
 
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
index e4fbdaec..0db4afd 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation.js
@@ -20,6 +20,9 @@
     /** @private {CommandParser} */
     this.commandParser_ = null;
 
+    /** @private {boolean} */
+    this.commandsFeatureEnabled_ = false;
+
     /**
      * The state of Dictation.
      * @private {!Dictation.DictationState}
@@ -42,6 +45,15 @@
     /** @private {?number} */
     this.timeoutId_ = null;
 
+    /** @private {?number} */
+    this.clearUITextTimeoutId_ = null;
+
+    /** @private {string} */
+    this.interimText_ = '';
+
+    /** @private {boolean} */
+    this.chromeVoxEnabled_ = false;
+
     this.initialize_();
   }
 
@@ -69,6 +81,15 @@
     // Browser process.
     chrome.accessibilityPrivate.onToggleDictation.addListener(
         activated => this.onToggleDictation_(activated));
+
+    chrome.accessibilityPrivate.isFeatureEnabled(
+        chrome.accessibilityPrivate.AccessibilityFeature.DICTATION_COMMANDS,
+        (result) => {
+          this.commandsFeatureEnabled_ = result;
+          if (this.commandsFeatureEnabled_) {
+            this.commandParser_.setCommandsEnabled();
+          }
+        });
   }
 
   /**
@@ -143,7 +164,7 @@
       return;
     }
     this.state_ = Dictation.DictationState.OFF;
-    if (this.inputController_.hasCompositionText()) {
+    if (this.inputController_.hasCompositionText() || this.interimText_) {
       this.endTone_.play();
     } else {
       this.cancelTone_.play();
@@ -157,6 +178,10 @@
       this.timeoutId_ = null;
     }
 
+    if (this.commandsFeatureEnabled_) {
+      this.inputController_.commitText(this.interimText_);
+      this.hideCommandsUI_();
+    }
     this.inputController_.disconnect();
     Dictation.removeAsInputMethod();
   }
@@ -190,12 +215,24 @@
   processSpeechRecognitionResult_(transcript, isFinal) {
     if (isFinal) {
       const command = this.commandParser_.parse(transcript);
-      this.inputController_.clearCompositionText(() => command.execute());
+      if (this.commandsFeatureEnabled_) {
+        if (command.execute()) {
+          this.showCommandExecuted_(command);
+        } else {
+          this.showCommandExecutionFailed_();
+        }
+      }
       if (command.isTextInput()) {
         this.inputController_.commitText(command.getText());
       }
-    } else if (this.speechRecognizer_.interimResults) {
-      this.inputController_.setCompositionText(transcript);
+    } else {
+      if (this.commandsFeatureEnabled_) {
+        this.setInterimText_(transcript);
+      } else if (!this.chromeVoxEnabled_) {
+        // When ChromeVox is enabled, we shouldn't populate interim
+        // composition results because it will increase the verbosity too much.
+        this.inputController_.setCompositionText(transcript);
+      }
     }
   }
 
@@ -209,6 +246,8 @@
       return;
     }
     this.state_ = Dictation.DictationState.LISTENING;
+    // Display the "....".
+    this.clearInterimText_();
   }
 
   /**
@@ -245,12 +284,10 @@
           }
           break;
         case Dictation.SPOKEN_FEEDBACK_PREF:
-          // When Spoken Feedback is enabled, we shouldn't populate interim
-          // results because it will increase the verbosity too much.
           if (pref.value) {
-            this.speechRecognizer_.interimResults = false;
+            this.chromeVoxEnabled_ = true;
           } else {
-            this.speechRecognizer_.interimResults = true;
+            this.chromeVoxEnabled_ = false;
           }
           break;
         default:
@@ -260,6 +297,106 @@
   }
 
   /**
+   * Shows the interim result in the UI.
+   * TODO(crbug.com/1252037): Implement with final design instead of input.ime.
+   * @param {string} text
+   * @private
+   */
+  setInterimText_(text) {
+    // TODO(crbug.com/1252037): Need to find a way to show interim text that is
+    // only whitespace. Google Cloud Speech can return a newline character
+    // although SODA does not seem to do that. The newline character looks wrong
+    // here.
+    this.interimText_ = text;
+    if (this.chromeVoxEnabled_) {
+      // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
+      return;
+    }
+    this.inputController_.showAnnotation(this.interimText_);
+    if (this.clearUITextTimeoutId_) {
+      clearTimeout(this.clearUITextTimeoutId_);
+      this.clearUITextTimeoutId_ = null;
+    }
+  }
+
+  /**
+   * Clears the interim result in the UI, replacing it with '....'.
+   * TODO(crbug.com/1252037): Implement with final design instead of input.ime.
+   * @private
+   */
+  clearInterimText_() {
+    if (this.chromeVoxEnabled_) {
+      // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
+      return;
+    }
+    this.interimText_ = '';
+    this.inputController_.showAnnotation('....');
+    if (this.clearUITextTimeoutId_) {
+      clearTimeout(this.clearUITextTimeoutId_);
+      this.clearUITextTimeoutId_ = null;
+    }
+  }
+
+  /**
+   * Shows that a command was executed in the UI.
+   * TODO(crbug.com/1252037): Implement with final design instead of input.ime.
+   * @param {Command} command
+   * @private
+   */
+  showCommandExecuted_(command) {
+    if (this.chromeVoxEnabled_) {
+      // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
+      return;
+    }
+    if (command.isTextInput()) {
+      // Return to the '....' UI.
+      this.clearInterimText_();
+      return;
+    }
+    this.interimText_ = '';
+    this.inputController_.showAnnotation(
+        '☑' + this.commandParser_.getCommandString(command));
+    this.clearUITextTimeoutId_ = setTimeout(
+        () => this.clearInterimText_(),
+        Dictation.Timeouts.SHOW_COMMAND_MESSAGE_MS);
+  }
+
+  /**
+   * Shows a message in the UI that a command failed to execute.
+   * TODO(crbug.com/1252037): Implement with final design instead of input.ime.
+   * @private
+   */
+  showCommandExecutionFailed_() {
+    if (this.chromeVoxEnabled_) {
+      // Using chrome.input.ime for UI causes too much verbosity with ChromeVox.
+      return;
+    }
+    this.interimText_ = '';
+    // TODO(crbug.com/1252037): Finalize string and internationalization.
+    this.inputController_.showAnnotation(`ⓘ We didn't recognize that`);
+    this.clearUITextTimeoutId_ = setTimeout(
+        () => this.clearInterimText_(),
+        Dictation.Timeouts.SHOW_COMMAND_MESSAGE_MS);
+  }
+
+  /**
+   * Hides the commands UI bubble.
+   * TODO(crbug.com/1252037): Implement with final design instead of input.ime.
+   * @private
+   */
+  hideCommandsUI_() {
+    if (this.chromeVoxEnabled_) {
+      return;
+    }
+    this.inputController_.hideAnnotation();
+    this.interimText_ = '';
+    if (this.clearUITextTimeoutId_) {
+      clearTimeout(this.clearUITextTimeoutId_);
+      this.clearUITextTimeoutId_ = null;
+    }
+  }
+
+  /**
    * Removes AccessibilityCommon as an input method so it doesn't show up in
    * the shelf input method picker UI.
    */
@@ -302,4 +439,5 @@
   NO_SPEECH_MS: 10 * 1000,
   NO_NEW_SPEECH_MS: 5 * 1000,
   NO_FOCUSED_IME_MS: 500,
+  SHOW_COMMAND_MESSAGE_MS: 2000,
 };
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test.js
index a87436a9..fe136ba 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/dictation_test.js
@@ -297,15 +297,30 @@
     'DictationE2ETest', 'InterimResultsDependOnChromeVoxEnabled',
     async function() {
       await this.waitForDictationModule();
-      assertEquals(true, mockSpeechRecognition.interimResults());
+      await this.toggleDictationAndStartListening(4);
+
+      // Interim results shown in composition.
+      mockSpeechRecognition.callOnResult('one', false);
+      this.assertImeCompositionParameters('one', 4);
+      this.mockInputIme.clearLastParameters();
+
       // Toggle ChromeVox on.
       await this.setPref(Dictation.SPOKEN_FEEDBACK_PREF, true);
       await this.getPref(Dictation.SPOKEN_FEEDBACK_PREF);
-      assertEquals(false, mockSpeechRecognition.interimResults());
+
+      // Composition is not changed.
+      mockSpeechRecognition.callOnResult('two', false);
+      assertFalse(!!this.mockInputIme.getLastCompositionParameters());
+
       // Toggle ChromeVox off.
       await this.setPref(Dictation.SPOKEN_FEEDBACK_PREF, false);
       await this.getPref(Dictation.SPOKEN_FEEDBACK_PREF);
-      assertEquals(true, mockSpeechRecognition.interimResults());
+
+      // Interim results impact the composition again.
+      mockSpeechRecognition.callOnResult('three', false);
+      this.assertImeCompositionParameters('three', 4);
+      this.mockInputIme.clearLastParameters();
+
     });
 
 SYNC_TEST_F(
@@ -551,7 +566,9 @@
       await this.toggleDictationAndStartListening(8);
       for (const command of this.commandStrings) {
         mockSpeechRecognition.callOnResult(command, false);
-        this.assertImeCompositionParameters(command, 8);
+        // Nothing is added to composition text when commands UI is enabled.
+        assertFalse(!!this.mockInputIme.getLastCompositionParameters());
+        // TODO(crbug.com/1252037): Check UI shows correct command info.
 
         mockSpeechRecognition.callOnResult(command, true);
         if (command === 'new line') {
diff --git a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
index cae0a4f..006dd0a 100644
--- a/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
+++ b/chrome/browser/resources/chromeos/accessibility/accessibility_common/dictation/input_controller.js
@@ -139,6 +139,44 @@
   }
 
   /**
+   * Shows an annotation in the candidate window.
+   * TODO(crbug.com/1252037): After implementing final UX design, remove
+   * this method from InputController.
+   * @param {string} annotation
+   */
+  showAnnotation(annotation) {
+    chrome.input.ime.setCandidateWindowProperties({
+      engineID: InputController.IME_ENGINE_ID,
+      properties: {
+        cursorVisible: true,
+        currentCandidateIndex: 0,
+        vertical: false,
+        visible: true,
+        windowPosition: 'cursor',
+        pageSize: 1
+      }
+    });
+    chrome.input.ime.setCandidates(
+        {
+          candidates: [{candidate: '', annotation, id: 1}],
+          contextID: this.activeImeContextId_,
+        },
+        (success) => {});
+  }
+
+  /**
+   * Hides the annotation and candidate window.
+   * TODO(crbug.com/1252037): After implementing final UX design, remove
+   * this method from InputController.
+   */
+  hideAnnotation() {
+    chrome.input.ime.setCandidateWindowProperties({
+      engineID: InputController.IME_ENGINE_ID,
+      properties: {visible: false}
+    });
+  }
+
+  /**
    * chrome.input.ime.onFocus callback. Save the active context ID, and
    * finish starting speech recognition if needed. This needs to be done
    * before starting recognition in order for browser tests to know that
diff --git a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js
index 7b834b2..a0f3780 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js
+++ b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_accessibility_private.js
@@ -24,6 +24,8 @@
     DICTATION_COMMANDS: 'dictation_commands',
   },
 
+  SyntheticKeyboardEventType: {KEYDOWN: 'keydown', KEYUP: 'keyup,'},
+
   /** @private {function<number, number>} */
   boundsListener_: null,
 
@@ -198,6 +200,12 @@
     callback(this.enabledFeatures_.has(feature));
   },
 
+  /**
+   * Creates a synthetic keyboard event.
+   * @param {Object} unused
+   */
+  sendSyntheticKeyEvent(unused) {},
+
   // Methods for testing. //
 
   /**
diff --git a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_input_ime.js b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_input_ime.js
index 0143fe0..18343dd9 100644
--- a/chrome/browser/resources/chromeos/accessibility/common/testing/mock_input_ime.js
+++ b/chrome/browser/resources/chromeos/accessibility/common/testing/mock_input_ime.js
@@ -89,7 +89,7 @@
     MockInputIme.lastCompositionParameters_ = composition;
   },
 
-  /** Clears compositoin text. */
+  /** Clears composition text. */
   clearComposition() {
     MockInputIme.lastCompositionParameters_ = null;
   },
@@ -99,6 +99,12 @@
     MockInputIme.lastCommittedParameters_ = commitParameters;
   },
 
+  /** @param {Object} unused */
+  setCandidateWindowProperties(unused) {},
+
+  /** @param {Object} unused */
+  setCandidates(unused) {},
+
   // Methods for testing. //
 
   /**
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/BUILD.gn b/chrome/browser/resources/chromeos/multidevice_internals/BUILD.gn
index efa5985..1fd2f48 100644
--- a/chrome/browser/resources/chromeos/multidevice_internals/BUILD.gn
+++ b/chrome/browser/resources/chromeos/multidevice_internals/BUILD.gn
@@ -34,6 +34,7 @@
   input_files = [
     "browser_tabs_metadata_form.js",
     "browser_tabs_model_form.js",
+    "camera_roll_manager_form.js",
     "logging_tab.js",
     "log_object.js",
     "multidevice_internals.js",
@@ -67,6 +68,7 @@
   is_polymer3 = true
   deps = [
     ":browser_tabs_metadata_form",
+    ":camera_roll_manager_form",
     ":log_object",
     ":logging_tab",
     ":multidevice_internals",
@@ -109,6 +111,13 @@
   deps = [ ":types" ]
 }
 
+js_library("camera_roll_manager_form") {
+  deps = [
+    ":multidevice_phonehub_browser_proxy",
+    ":types",
+  ]
+}
+
 js_library("i18n_setup") {
   deps = [ "//ui/webui/resources/js:load_time_data.m" ]
 }
@@ -178,6 +187,7 @@
 js_library("phonehub_tab") {
   deps = [
     ":browser_tabs_model_form",
+    ":camera_roll_manager_form",
     ":i18n_setup",
     ":multidevice_phonehub_browser_proxy",
     ":notification_manager",
@@ -209,5 +219,6 @@
     "browser_tabs_model_form.js",
     "notification_form.js",
     "notification_manager.js",
+    "camera_roll_manager_form.js",
   ]
 }
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/camera_roll_manager_form.html b/chrome/browser/resources/chromeos/multidevice_internals/camera_roll_manager_form.html
new file mode 100644
index 0000000..74e6b8c
--- /dev/null
+++ b/chrome/browser/resources/chromeos/multidevice_internals/camera_roll_manager_form.html
@@ -0,0 +1,38 @@
+<style include="cr-shared-style shared-style">
+  :host {
+    display: flex;
+    flex: 0 0 100%;
+  }
+
+  .camera-roll-property {
+    flex-basis: 100%;
+    justify-content: center;
+  }
+
+  #cameraRollPropertiesColumn {
+    flex: 2;
+    flex-wrap: wrap;
+  }
+</style>
+
+<div class="column">
+  <cr-button on-click="setFakeCameraRollManager_" class="internals-button">
+    <span class="emphasize">Change Camera Roll Status</span>
+  </cr-button>
+  <div class="label">
+    <span class="emphasize">Note:</span> Click the button above to propagate all
+    camera roll values on the right hand side to the fake phonehub manager.
+  </div>
+</div>
+<div id="cameraRollPropertiesColumn" class="column">
+  <div class="camera-roll-property">
+    <div class="label">
+      Number of Thumbnails
+    </div>
+    <cr-input id="numberOfThumbnailsInput" type="number"
+        min="0" max="16" value="{{numberOfThumbnails_}}"
+        on-change="onNumberOfThumbnailsChanged_"
+        auto-validate error-message="Must be [0, 16]">
+    </cr-input>
+  </div>
+</div>
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/camera_roll_manager_form.js b/chrome/browser/resources/chromeos/multidevice_internals/camera_roll_manager_form.js
new file mode 100644
index 0000000..305e0d4f08c
--- /dev/null
+++ b/chrome/browser/resources/chromeos/multidevice_internals/camera_roll_manager_form.js
@@ -0,0 +1,59 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/shared_style_css.m.js';
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_elements/cr_input/cr_input.m.js';
+import './shared_style.js';
+
+import {html, Polymer} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {MultidevicePhoneHubBrowserProxy} from './multidevice_phonehub_browser_proxy.js';
+import {CameraRollManager} from './types.js';
+
+Polymer({
+  is: 'camera-roll-manager-form',
+
+  _template: html`{__html_template__}`,
+
+  properties: {
+    /** @private */
+    numberOfThumbnails_: {
+      type: Number,
+      value: 4,
+    },
+  },
+
+  /** @private {?MultidevicePhoneHubBrowserProxy}*/
+  browserProxy_: null,
+
+  /** @override */
+  created() {
+    this.browserProxy_ = MultidevicePhoneHubBrowserProxy.getInstance();
+  },
+
+  /** @private */
+  onNumberOfThumbnailsChanged_() {
+    const inputValue = this.$$('#numberOfThumbnailsInput').value;
+    if (inputValue > 16) {
+      this.numberOfThumbnails_ = 16;
+      return;
+    }
+
+    if (inputValue < 0) {
+      this.numberOfThumbnails_ = 0;
+      return;
+    }
+
+    this.numberOfThumbnails_ = Number(inputValue);
+  },
+
+  /** @private */
+  setFakeCameraRollManager_() {
+    const cameraRollManager = {
+      numberOfThumbnails: this.numberOfThumbnails_,
+    };
+    this.browserProxy_.setCameraRoll(cameraRollManager);
+  },
+});
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/multidevice_phonehub_browser_proxy.js b/chrome/browser/resources/chromeos/multidevice_internals/multidevice_phonehub_browser_proxy.js
index ebe348e..17c0a04 100644
--- a/chrome/browser/resources/chromeos/multidevice_internals/multidevice_phonehub_browser_proxy.js
+++ b/chrome/browser/resources/chromeos/multidevice_internals/multidevice_phonehub_browser_proxy.js
@@ -4,7 +4,7 @@
 
 import {addSingletonGetter} from 'chrome://resources/js/cr.m.js';
 
-import {BrowserTabsModel, FeatureStatus, FindMyDeviceStatus, Notification, PhoneStatusModel, TetherStatus} from './types.js';
+import {BrowserTabsModel, CameraRollManager, FeatureStatus, FindMyDeviceStatus, Notification, PhoneStatusModel, TetherStatus} from './types.js';
 
 /**
  * JavaScript hooks into the native WebUI handler for Phonehub tab.
@@ -114,6 +114,15 @@
   resetHasNotificationSetupUiBeenDismissed() {
     chrome.send('resetHasNotificationSetupUiBeenDismissed');
   }
+
+  /**
+   * Sets the camera roll manager.
+   * @param {!CameraRollManager} cameraRollManager The camera roll with fake
+   *     values.
+   */
+  setCameraRoll(cameraRollManager) {
+    chrome.send('setCameraRoll', [cameraRollManager]);
+  }
 }
 
 addSingletonGetter(MultidevicePhoneHubBrowserProxy);
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.html b/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.html
index 61b88c1..1071f29 100644
--- a/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.html
+++ b/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.html
@@ -95,6 +95,9 @@
       <div class="cr-row">
         <notification-manager></notification-manager>
       </div>
+      <div class="cr-row">
+        <camera-roll-manager-form></camera-roll-manager-form>
+      </div>
     </template>
   </template>
 </template>
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.js b/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.js
index 980fc88..80cc2e5 100644
--- a/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.js
+++ b/chrome/browser/resources/chromeos/multidevice_internals/phonehub_tab.js
@@ -7,6 +7,7 @@
 import 'chrome://resources/cr_elements/md_select_css.m.js';
 import 'chrome://resources/cr_elements/shared_style_css.m.js';
 import './browser_tabs_model_form.js';
+import './camera_roll_manager_form.js';
 import './i18n_setup.js';
 import './phone_name_form.js';
 import './phone_status_model_form.js';
diff --git a/chrome/browser/resources/chromeos/multidevice_internals/types.js b/chrome/browser/resources/chromeos/multidevice_internals/types.js
index 443f6e8..a529ad2 100644
--- a/chrome/browser/resources/chromeos/multidevice_internals/types.js
+++ b/chrome/browser/resources/chromeos/multidevice_internals/types.js
@@ -249,3 +249,10 @@
   [FindMyDeviceStatus.OFF, 'Off'],
   [FindMyDeviceStatus.ON, 'On'],
 ]);
+
+/**
+ * @typedef {{
+ *   numberOfThumbnails: number,
+ * }}
+ */
+export let CameraRollManager;
diff --git a/chrome/browser/resources/print_preview/BUILD.gn b/chrome/browser/resources/print_preview/BUILD.gn
index ee61686..d221d83 100644
--- a/chrome/browser/resources/print_preview/BUILD.gn
+++ b/chrome/browser/resources/print_preview/BUILD.gn
@@ -123,9 +123,9 @@
     "ui/button_strip.js",
     "ui/color_settings.js",
     "ui/copies_settings.js",
-    "ui/destination_dialog_css.js",
-    "ui/destination_list.js",
-    "ui/destination_list_item.js",
+    "ui/destination_dialog_css.ts",
+    "ui/destination_list.ts",
+    "ui/destination_list_item.ts",
     "ui/destination_select_css.js",
     "ui/destination_settings.js",
     "ui/dpi_settings.js",
@@ -158,14 +158,14 @@
       "ui/destination_dropdown_cros.js",
       "ui/destination_select_cros.js",
       "ui/pin_settings.js",
-      "ui/provisional_destination_resolver.js",
-      "ui/destination_dialog_cros.js",
+      "ui/provisional_destination_resolver.ts",
+      "ui/destination_dialog_cros.ts",
     ]
   } else {
     in_files += [
       "ui/destination_select.js",
       "ui/link_container.js",
-      "ui/destination_dialog.js",
+      "ui/destination_dialog.ts",
     ]
   }
 }
@@ -264,9 +264,9 @@
     "ui/button_strip.js",
     "ui/color_settings.js",
     "ui/copies_settings.js",
-    "ui/destination_dialog_css.js",
-    "ui/destination_list.js",
-    "ui/destination_list_item.js",
+    "ui/destination_dialog_css.ts",
+    "ui/destination_list.ts",
+    "ui/destination_list_item.ts",
     "ui/destination_select_css.js",
     "ui/destination_settings.js",
     "ui/dpi_settings.js",
@@ -304,15 +304,15 @@
       "data/print_server_store.ts",
       "data/printer_status_cros.ts",
       "native_layer_cros.ts",
-      "ui/destination_dialog_cros.js",
+      "ui/destination_dialog_cros.ts",
       "ui/destination_dropdown_cros.js",
       "ui/destination_select_cros.js",
       "ui/pin_settings.js",
-      "ui/provisional_destination_resolver.js",
+      "ui/provisional_destination_resolver.ts",
     ]
   } else {
     in_files += [
-      "ui/destination_dialog.js",
+      "ui/destination_dialog.ts",
       "ui/destination_select.js",
       "ui/link_container.js",
     ]
diff --git a/chrome/browser/resources/print_preview/ui/BUILD.gn b/chrome/browser/resources/print_preview/ui/BUILD.gn
index 5db779b..db1e7ae1 100644
--- a/chrome/browser/resources/print_preview/ui/BUILD.gn
+++ b/chrome/browser/resources/print_preview/ui/BUILD.gn
@@ -14,9 +14,9 @@
     "button_strip.js",
     "color_settings.js",
     "copies_settings.js",
-    "destination_dialog_css.js",
-    "destination_list_item.js",
-    "destination_list.js",
+    "destination_dialog_css.ts",
+    "destination_list_item.ts",
+    "destination_list.ts",
     "destination_select_css.js",
     "destination_settings.js",
     "dpi_settings.js",
@@ -46,15 +46,15 @@
   ]
   if (is_chromeos) {
     js_files += [
-      "destination_dialog_cros.js",
+      "destination_dialog_cros.ts",
       "destination_dropdown_cros.js",
       "destination_select_cros.js",
       "pin_settings.js",
-      "provisional_destination_resolver.js",
+      "provisional_destination_resolver.ts",
     ]
   } else {
     js_files += [
-      "destination_dialog.js",
+      "destination_dialog.ts",
       "destination_select.js",
     ]
   }
diff --git a/chrome/browser/resources/print_preview/ui/destination_dialog.js b/chrome/browser/resources/print_preview/ui/destination_dialog.ts
similarity index 74%
rename from chrome/browser/resources/print_preview/ui/destination_dialog.js
rename to chrome/browser/resources/print_preview/ui/destination_dialog.ts
index 6b537e0..9d3fb2b 100644
--- a/chrome/browser/resources/print_preview/ui/destination_dialog.js
+++ b/chrome/browser/resources/print_preview/ui/destination_dialog.ts
@@ -21,9 +21,10 @@
 import './throbber_css.js';
 import './destination_list_item.js';
 
+import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
-import {ListPropertyUpdateBehavior, ListPropertyUpdateBehaviorInterface} from 'chrome://resources/js/list_property_update_behavior.m.js';
+import {ListPropertyUpdateBehavior} from 'chrome://resources/js/list_property_update_behavior.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {beforeNextRender, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
@@ -33,17 +34,19 @@
 import {NativeLayerImpl} from '../native_layer.js';
 
 import {PrintPreviewDestinationListItemElement} from './destination_list_item.js';
+import {PrintPreviewSearchBoxElement} from './print_preview_search_box.js';
 
+export interface PrintPreviewDestinationDialogElement {
+  $: {
+    dialog: CrDialogElement,
+    searchBox: PrintPreviewSearchBoxElement,
+  };
+}
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {ListPropertyUpdateBehaviorInterface}
- */
 const PrintPreviewDestinationDialogElementBase =
-    mixinBehaviors([ListPropertyUpdateBehavior], PolymerElement);
+    mixinBehaviors([ListPropertyUpdateBehavior], PolymerElement) as
+    {new (): PolymerElement & ListPropertyUpdateBehavior};
 
-/** @polymer */
 export class PrintPreviewDestinationDialogElement extends
     PrintPreviewDestinationDialogElementBase {
   static get is() {
@@ -56,7 +59,6 @@
 
   static get properties() {
     return {
-      /** @type {?DestinationStore} */
       destinationStore: {
         type: Object,
         observer: 'onDestinationStoreSet_',
@@ -69,25 +71,20 @@
 
       currentDestinationAccount: String,
 
-      /** @type {!Array<string>} */
       users: Array,
 
-      /** @private {!Array<!Destination>} */
       destinations_: {
         type: Array,
         value: [],
       },
 
-      /** @private {boolean} */
       loadingDestinations_: {
         type: Boolean,
         value: false,
       },
 
-      /** @private {!MetricsContext} */
       metrics_: Object,
 
-      /** @private {?RegExp} */
       searchQuery_: {
         type: Object,
         value: null,
@@ -95,44 +92,35 @@
     };
   }
 
-  constructor() {
-    super();
+  destinationStore: DestinationStore;
+  activeUser: string;
+  currentDestinationAccount: string;
+  users: string[];
+  private destinations_: Destination[];
+  private loadingDestinations_: boolean;
+  private metrics_: MetricsContext;
+  private searchQuery_: RegExp|null;
 
-    /** @private {!EventTracker} */
-    this.tracker_ = new EventTracker();
+  private tracker_: EventTracker = new EventTracker();
+  private initialized_: boolean = false;
 
-    /** @private {boolean} */
-    this.initialized_ = false;
-  }
-
-  /** @override */
   ready() {
     super.ready();
-    this.addEventListener(
-        'keydown', e => this.onKeydown_(/** @type {!KeyboardEvent} */ (e)));
+    this.addEventListener('keydown', (e: KeyboardEvent) => this.onKeydown_(e));
   }
 
-  /** @override */
   disconnectedCallback() {
     super.disconnectedCallback();
 
     this.tracker_.removeAll();
   }
 
-  /**
-   * @param {string} account
-   * @private
-   */
-  fireAccountChange_(account) {
+  private fireAccountChange_(account: string) {
     this.dispatchEvent(new CustomEvent(
         'account-change', {bubbles: true, composed: true, detail: account}));
   }
 
-  /**
-   * @param {!KeyboardEvent} e Event containing the key
-   * @private
-   */
-  onKeydown_(e) {
+  private onKeydown_(e: KeyboardEvent) {
     e.stopPropagation();
     const searchInput = this.$.searchBox.getSearchInput();
     if (e.key === 'Escape' &&
@@ -142,8 +130,7 @@
     }
   }
 
-  /** @private */
-  onDestinationStoreSet_() {
+  private onDestinationStoreSet_() {
     assert(this.destinations_.length === 0);
     const destinationStore = assert(this.destinationStore);
     this.tracker_.add(
@@ -155,17 +142,15 @@
     this.initialized_ = true;
   }
 
-  /** @private */
-  onActiveUserChange_() {
+  private onActiveUserChange_() {
     if (this.activeUser) {
-      this.shadowRoot.querySelector('select').value = this.activeUser;
+      this.shadowRoot!.querySelector('select')!.value = this.activeUser;
     }
 
     this.updateDestinations_();
   }
 
-  /** @private */
-  updateDestinations_() {
+  private updateDestinations_() {
     if (this.destinationStore === undefined || !this.initialized_) {
       return;
     }
@@ -178,18 +163,13 @@
         this.destinationStore.isPrintDestinationSearchInProgress;
   }
 
-  /**
-   * @return {!Array<!Destination>}
-   * @private
-   */
-  getDestinationList_() {
+  private getDestinationList_(): Destination[] {
     const destinations = this.destinationStore.destinations(this.activeUser);
 
     return destinations;
   }
 
-  /** @private */
-  onCloseOrCancel_() {
+  private onCloseOrCancel_() {
     if (this.searchQuery_) {
       this.$.searchBox.setValue('');
     }
@@ -203,17 +183,15 @@
     }
   }
 
-  /** @private */
-  onCancelButtonClick_() {
+  private onCancelButtonClick_() {
     this.$.dialog.cancel();
   }
 
   /**
-   * @param {!CustomEvent<!PrintPreviewDestinationListItemElement>} e Event
-   *     containing the selected destination list item element.
-   * @private
+   * @param e Event containing the selected destination list item element.
    */
-  onDestinationSelected_(e) {
+  private onDestinationSelected_(
+      e: CustomEvent<PrintPreviewDestinationListItemElement>) {
     const listItem = e.detail;
     const destination = listItem.destination;
 
@@ -223,11 +201,7 @@
     this.selectDestination_(destination);
   }
 
-  /**
-   * @param {!Destination} destination The destination to select.
-   * @private
-   */
-  selectDestination_(destination) {
+  private selectDestination_(destination: Destination) {
     this.destinationStore.selectDestination(destination);
     this.$.dialog.close();
   }
@@ -241,20 +215,19 @@
         this.destinationStore.isPrintDestinationSearchInProgress;
     this.metrics_.record(DestinationSearchBucket.DESTINATION_SHOWN);
     if (this.activeUser) {
-      beforeNextRender(assert(this.shadowRoot.querySelector('select')), () => {
-        this.shadowRoot.querySelector('select').value = this.activeUser;
+      beforeNextRender(assert(this.shadowRoot!.querySelector('select')), () => {
+        this.shadowRoot!.querySelector('select')!.value = this.activeUser;
       });
     }
   }
 
-  /** @return {boolean} Whether the dialog is open. */
-  isOpen() {
+  /** @return Whether the dialog is open. */
+  isOpen(): boolean {
     return this.$.dialog.hasAttribute('open');
   }
 
-  /** @private */
-  onUserChange_() {
-    const select = this.shadowRoot.querySelector('select');
+  private onUserChange_() {
+    const select = this.shadowRoot!.querySelector('select')!;
     const account = select.value;
     if (account) {
       this.loadingDestinations_ = true;
@@ -267,8 +240,7 @@
     }
   }
 
-  /** @private */
-  onManageButtonClick_() {
+  private onManageButtonClick_() {
     this.metrics_.record(DestinationSearchBucket.MANAGE_BUTTON_CLICKED);
     NativeLayerImpl.getInstance().managePrinters();
   }
diff --git a/chrome/browser/resources/print_preview/ui/destination_dialog_cros.js b/chrome/browser/resources/print_preview/ui/destination_dialog_cros.ts
similarity index 73%
rename from chrome/browser/resources/print_preview/ui/destination_dialog_cros.js
rename to chrome/browser/resources/print_preview/ui/destination_dialog_cros.ts
index 6bd8ffe8..7d33607 100644
--- a/chrome/browser/resources/print_preview/ui/destination_dialog_cros.js
+++ b/chrome/browser/resources/print_preview/ui/destination_dialog_cros.ts
@@ -23,11 +23,12 @@
 import './throbber_css.js';
 import './destination_list_item.js';
 
+import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
 import {assert} from 'chrome://resources/js/assert.m.js';
 import {EventTracker} from 'chrome://resources/js/event_tracker.m.js';
-import {ListPropertyUpdateBehavior, ListPropertyUpdateBehaviorInterface} from 'chrome://resources/js/list_property_update_behavior.m.js';
+import {ListPropertyUpdateBehavior} from 'chrome://resources/js/list_property_update_behavior.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
-import {WebUIListenerBehavior, WebUIListenerBehaviorInterface} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
+import {WebUIListenerBehavior} from 'chrome://resources/js/web_ui_listener_behavior.m.js';
 import {beforeNextRender, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Destination, GooglePromotedDestinationId} from '../data/destination.js';
@@ -38,18 +39,30 @@
 import {PrintServer, PrintServersConfig} from '../native_layer_cros.js';
 
 import {PrintPreviewDestinationListItemElement} from './destination_list_item.js';
+import {PrintPreviewSearchBoxElement} from './print_preview_search_box.js';
+import {PrintPreviewProvisionalDestinationResolverElement} from './provisional_destination_resolver.js';
 
+type PrintServersChangedEventDetail = {
+  printServerNames: string[],
+  isSingleServerFetchingMode: boolean,
+};
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {ListPropertyUpdateBehaviorInterface}
- * @implements {WebUIListenerBehaviorInterface}
- */
-const PrintPreviewDestinationDialogCrosElementBase = mixinBehaviors(
-    [ListPropertyUpdateBehavior, WebUIListenerBehavior], PolymerElement);
+export interface PrintPreviewDestinationDialogCrosElement {
+  $: {
+    dialog: CrDialogElement,
+    provisionalResolver: PrintPreviewProvisionalDestinationResolverElement,
+    searchBox: PrintPreviewSearchBoxElement,
+  };
+}
 
-/** @polymer */
+const PrintPreviewDestinationDialogCrosElementBase =
+    mixinBehaviors(
+        [ListPropertyUpdateBehavior, WebUIListenerBehavior], PolymerElement) as
+    {
+      new ():
+          PolymerElement & WebUIListenerBehavior & ListPropertyUpdateBehavior
+    };
+
 export class PrintPreviewDestinationDialogCrosElement extends
     PrintPreviewDestinationDialogCrosElementBase {
   static get is() {
@@ -62,7 +75,6 @@
 
   static get properties() {
     return {
-      /** @type {?DestinationStore} */
       destinationStore: {
         type: Object,
         observer: 'onDestinationStoreSet_',
@@ -75,44 +87,36 @@
 
       currentDestinationAccount: String,
 
-      /** @type {!Array<string>} */
       users: Array,
 
-      /** @private */
       printServerSelected_: {
         type: String,
         value: '',
         observer: 'onPrintServerSelected_',
       },
 
-      /** @private {!Array<!Destination>} */
       destinations_: {
         type: Array,
-        value: [],
+        value: () => [],
       },
 
-      /** @private {boolean} */
       loadingDestinations_: {
         type: Boolean,
         value: false,
       },
 
-      /** @private {!MetricsContext} */
       metrics_: Object,
 
-      /** @private {?RegExp} */
       searchQuery_: {
         type: Object,
         value: null,
       },
 
-      /** @private {boolean} */
       isSingleServerFetchingMode_: {
         type: Boolean,
         value: false,
       },
 
-      /** @private {!Array<string>} */
       printServerNames_: {
         type: Array,
         value() {
@@ -120,13 +124,11 @@
         },
       },
 
-      /** @private {boolean} */
       loadingServerPrinters_: {
         type: Boolean,
         value: false,
       },
 
-      /** @private {boolean} */
       loadingAnyDestinations_: {
         type: Boolean,
         computed: 'computeLoadingDestinations_(' +
@@ -135,45 +137,45 @@
     };
   }
 
-  constructor() {
-    super();
+  destinationStore: DestinationStore;
+  activeUser: string;
+  currentDestinationAccount: string;
+  users: string[];
+  private printServerSelected_: string;
+  private destinations_: Destination[];
+  private loadingDestinations_: boolean;
+  private metrics_: MetricsContext;
+  private searchQuery_: RegExp|null;
+  private isSingleServerFetchingMode_: boolean;
+  private printServerNames_: string[];
+  private loadingServerPrinters_: boolean;
+  private loadingAnyDestinations_: boolean;
 
-    /** @private {!EventTracker} */
-    this.tracker_ = new EventTracker();
+  private tracker_: EventTracker = new EventTracker();
+  private destinationInConfiguring_: Destination|null = null;
+  private initialized_: boolean = false;
+  private printServerStore_: PrintServerStore|null = null;
 
-    /** @private {?Destination} */
-    this.destinationInConfiguring_ = null;
-
-    /** @private {boolean} */
-    this.initialized_ = false;
-
-    /** @private {?PrintServerStore} */
-    this.printServerStore_ = null;
-  }
-
-  /** @override */
   disconnectedCallback() {
     super.disconnectedCallback();
 
     this.tracker_.removeAll();
   }
 
-  /** @override */
   ready() {
     super.ready();
 
-    this.addEventListener(
-        'keydown', e => this.onKeydown_(/** @type {!KeyboardEvent} */ (e)));
+    this.addEventListener('keydown', e => this.onKeydown_(e as KeyboardEvent));
     this.printServerStore_ = new PrintServerStore(
-        (/** string */ eventName, /** !Function */ callback) =>
-            void this.addWebUIListener(eventName, callback));
+        (eventName: string, callback: (p: any) => void) =>
+            this.addWebUIListener(eventName, callback));
     this.tracker_.add(
         this.printServerStore_, PrintServerStoreEventType.PRINT_SERVERS_CHANGED,
-        event => void this.onPrintServersChanged_(event));
+        this.onPrintServersChanged_.bind(this));
     this.tracker_.add(
         this.printServerStore_,
         PrintServerStoreEventType.SERVER_PRINTERS_LOADING,
-        event => void this.onServerPrintersLoading_(event));
+        this.onServerPrintersLoading_.bind(this));
     this.printServerStore_.getPrintServersConfig().then(config => {
       this.printServerNames_ =
           config.printServers.map(printServer => printServer.name);
@@ -184,20 +186,12 @@
     }
   }
 
-  /**
-   * @param {string} account
-   * @private
-   */
-  fireAccountChange_(account) {
+  private fireAccountChange_(account: string) {
     this.dispatchEvent(new CustomEvent(
         'account-change', {bubbles: true, composed: true, detail: account}));
   }
 
-  /**
-   * @param {!KeyboardEvent} e Event containing the key
-   * @private
-   */
-  onKeydown_(e) {
+  private onKeydown_(e: KeyboardEvent) {
     e.stopPropagation();
     const searchInput = this.$.searchBox.getSearchInput();
     if (e.key === 'Escape' &&
@@ -207,8 +201,7 @@
     }
   }
 
-  /** @private */
-  onDestinationStoreSet_() {
+  private onDestinationStoreSet_() {
     assert(this.destinations_.length === 0);
     const destinationStore = assert(this.destinationStore);
     this.tracker_.add(
@@ -223,17 +216,15 @@
     }
   }
 
-  /** @private */
-  onActiveUserChange_() {
+  private onActiveUserChange_() {
     if (this.activeUser) {
-      this.shadowRoot.querySelector('select').value = this.activeUser;
+      this.shadowRoot!.querySelector('select')!.value = this.activeUser;
     }
 
     this.updateDestinations_();
   }
 
-  /** @private */
-  updateDestinations_() {
+  private updateDestinations_() {
     if (this.destinationStore === undefined || !this.initialized_) {
       return;
     }
@@ -246,11 +237,7 @@
         this.destinationStore.isPrintDestinationSearchInProgress;
   }
 
-  /**
-   * @return {!Array<!Destination>}
-   * @private
-   */
-  getDestinationList_() {
+  private getDestinationList_(): Destination[] {
     // Filter out the 'Save to Drive' option so it is not shown in the
     // list of available options.
     return this.destinationStore.destinations(this.activeUser)
@@ -261,8 +248,7 @@
                     GooglePromotedDestinationId.SAVE_TO_DRIVE_CROS);
   }
 
-  /** @private */
-  onCloseOrCancel_() {
+  private onCloseOrCancel_() {
     if (this.searchQuery_) {
       this.$.searchBox.setValue('');
     }
@@ -276,17 +262,15 @@
     }
   }
 
-  /** @private */
-  onCancelButtonClick_() {
+  private onCancelButtonClick_() {
     this.$.dialog.cancel();
   }
 
   /**
-   * @param {!CustomEvent<!PrintPreviewDestinationListItemElement>} e Event
-   *     containing the selected destination list item element.
-   * @private
+   * @param e Event containing the selected destination list item element.
    */
-  onDestinationSelected_(e) {
+  private onDestinationSelected_(
+      e: CustomEvent<PrintPreviewDestinationListItemElement>) {
     const listItem = e.detail;
     const destination = listItem.destination;
 
@@ -340,11 +324,7 @@
             });
   }
 
-  /**
-   * @param {!Destination} destination The destination to select.
-   * @private
-   */
-  selectDestination_(destination) {
+  private selectDestination_(destination: Destination) {
     this.destinationStore.selectDestination(destination);
     this.$.dialog.close();
   }
@@ -358,22 +338,18 @@
         this.destinationStore.isPrintDestinationSearchInProgress;
     this.metrics_.record(DestinationSearchBucket.DESTINATION_SHOWN);
     if (this.activeUser) {
-      beforeNextRender(assert(this.shadowRoot.querySelector('select')), () => {
-        this.shadowRoot.querySelector('select').value = this.activeUser;
+      beforeNextRender(assert(this.shadowRoot!.querySelector('select')), () => {
+        this.shadowRoot!.querySelector('select')!.value = this.activeUser;
       });
     }
   }
 
-  /** @return {boolean} Whether the dialog is open. */
-  isOpen() {
+  /** @return Whether the dialog is open. */
+  isOpen(): boolean {
     return this.$.dialog.hasAttribute('open');
   }
 
-  /**
-   * @param {string} printServerName The name of the print server.
-   * @private
-   */
-  onPrintServerSelected_(printServerName) {
+  private onPrintServerSelected_(printServerName: string) {
     if (!this.printServerStore_) {
       return;
     }
@@ -381,36 +357,27 @@
   }
 
   /**
-   * @param {!CustomEvent<!{printServerNames: !Array<string>,
-   *     isSingleServerFetchingMode: boolean}>} e Event containing the current
-   *     print server names and fetching mode.
-   * @private
+   * @param e Event containing the current print server names and fetching mode.
    */
-  onPrintServersChanged_(e) {
+  private onPrintServersChanged_(
+      e: CustomEvent<PrintServersChangedEventDetail>) {
     this.isSingleServerFetchingMode_ = e.detail.isSingleServerFetchingMode;
     this.printServerNames_ = e.detail.printServerNames;
   }
 
   /**
-   * @param {!CustomEvent<boolean>} e Event containing whether server printers
-   *     are currently loading.
-   * @private
+   * @param e Event containing whether server printers are currently loading.
    */
-  onServerPrintersLoading_(e) {
+  private onServerPrintersLoading_(e: CustomEvent<boolean>) {
     this.loadingServerPrinters_ = e.detail;
   }
 
-  /**
-   * @return {boolean} Whether the destinations are loading.
-   * @private
-   */
-  computeLoadingDestinations_() {
+  private computeLoadingDestinations_(): boolean {
     return this.loadingDestinations_ || this.loadingServerPrinters_;
   }
 
-  /** @private */
-  onUserChange_() {
-    const select = this.shadowRoot.querySelector('select');
+  private onUserChange_() {
+    const select = this.shadowRoot!.querySelector('select')!;
     const account = select.value;
     if (account) {
       this.loadingDestinations_ = true;
@@ -423,8 +390,7 @@
     }
   }
 
-  /** @private */
-  onManageButtonClick_() {
+  private onManageButtonClick_() {
     this.metrics_.record(DestinationSearchBucket.MANAGE_BUTTON_CLICKED);
     NativeLayerImpl.getInstance().managePrinters();
   }
diff --git a/chrome/browser/resources/print_preview/ui/destination_dialog_css.js b/chrome/browser/resources/print_preview/ui/destination_dialog_css.ts
similarity index 100%
rename from chrome/browser/resources/print_preview/ui/destination_dialog_css.js
rename to chrome/browser/resources/print_preview/ui/destination_dialog_css.ts
diff --git a/chrome/browser/resources/print_preview/ui/destination_list.js b/chrome/browser/resources/print_preview/ui/destination_list.ts
similarity index 76%
rename from chrome/browser/resources/print_preview/ui/destination_list.js
rename to chrome/browser/resources/print_preview/ui/destination_list.ts
index 868b5e3..0331918 100644
--- a/chrome/browser/resources/print_preview/ui/destination_list.js
+++ b/chrome/browser/resources/print_preview/ui/destination_list.ts
@@ -10,22 +10,24 @@
 import '../strings.m.js';
 import './throbber_css.js';
 
-import {ListPropertyUpdateBehavior, ListPropertyUpdateBehaviorInterface} from 'chrome://resources/js/list_property_update_behavior.m.js';
+import {ListPropertyUpdateBehavior} from 'chrome://resources/js/list_property_update_behavior.m.js';
+import {IronListElement} from 'chrome://resources/polymer/v3_0/iron-list/iron-list.js';
 import {afterNextRender, html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {Destination} from '../data/destination.js';
 
 const DESTINATION_ITEM_HEIGHT = 32;
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {ListPropertyUpdateBehaviorInterface}
- */
-const PrintPreviewDestinationListElementBase =
-    mixinBehaviors([ListPropertyUpdateBehavior], PolymerElement);
+export interface PrintPreviewDestinationListElement {
+  $: {
+    list: IronListElement,
+  };
+}
 
-/** @polymer */
+const PrintPreviewDestinationListElementBase =
+    mixinBehaviors([ListPropertyUpdateBehavior], PolymerElement) as
+    {new (): ListPropertyUpdateBehavior & PolymerElement};
+
 export class PrintPreviewDestinationListElement extends
     PrintPreviewDestinationListElementBase {
   static get is() {
@@ -38,37 +40,30 @@
 
   static get properties() {
     return {
-      /** @type {Array<!Destination>} */
       destinations: Array,
 
-      /** @type {?RegExp} */
       searchQuery: Object,
 
-      /** @type {boolean} */
       loadingDestinations: {
         type: Boolean,
         value: false,
       },
 
-      /** @private {!Array<!Destination>} */
       matchingDestinations_: {
         type: Array,
         value: () => [],
       },
 
-      /** @private {boolean} */
       hasDestinations_: {
         type: Boolean,
         value: true,
       },
 
-      /** @private {boolean} */
       throbberHidden_: {
         type: Boolean,
         value: false,
       },
 
-      /** @private */
       hideList_: {
         type: Boolean,
         value: false,
@@ -76,22 +71,23 @@
     };
   }
 
+  destinations: Destination[];
+  searchQuery: RegExp|null;
+  loadingDestinations: boolean;
+  private matchingDestinations_: Destination[];
+  private hasDestinations_: boolean;
+  private throbberHidden_: boolean;
+  private hideList_: boolean;
+
+  private boundUpdateHeight_: ((e: Event) => void)|null = null;
+
   static get observers() {
     return [
       'updateMatchingDestinations_(' +
           'destinations.*, searchQuery, loadingDestinations)',
-
     ];
   }
 
-  constructor() {
-    super();
-
-    /** @private {?function(Event)} */
-    this.boundUpdateHeight_ = null;
-  }
-
-  /** @override */
   connectedCallback() {
     super.connectedCallback();
 
@@ -99,11 +95,10 @@
     window.addEventListener('resize', this.boundUpdateHeight_);
   }
 
-  /** @override */
   disconnectedCallback() {
     super.disconnectedCallback();
 
-    window.removeEventListener('resize', this.boundUpdateHeight_);
+    window.removeEventListener('resize', this.boundUpdateHeight_!);
     this.boundUpdateHeight_ = null;
   }
 
@@ -114,17 +109,12 @@
    * (a known iron-list issue). The event needs to be fired while the list is
    * visible, so firing it immediately when the change occurs does not always
    * work.
-   * @private
    */
-  forceIronResize_() {
+  private forceIronResize_() {
     this.$.list.fire('iron-resize');
   }
 
-  /**
-   * @param {number=} numDestinations
-   * @private
-   */
-  updateHeight_(numDestinations) {
+  private updateHeight_(numDestinations?: number) {
     const count = numDestinations === undefined ?
         this.matchingDestinations_.length :
         numDestinations;
@@ -149,15 +139,13 @@
         `${DESTINATION_ITEM_HEIGHT}px`;
   }
 
-  /** @private */
-  updateMatchingDestinations_() {
+  private updateMatchingDestinations_() {
     if (this.destinations === undefined) {
       return;
     }
 
     const matchingDestinations = this.searchQuery ?
-        this.destinations.filter(
-            d => d.matches(/** @type {!RegExp} */ (this.searchQuery))) :
+        this.destinations.filter(d => d.matches(this.searchQuery!)) :
         this.destinations.slice();
 
     // Update the height before updating the list.
@@ -169,11 +157,7 @@
     this.forceIronResize_();
   }
 
-  /**
-   * @param {!KeyboardEvent} e Event containing the destination and key.
-   * @private
-   */
-  onKeydown_(e) {
+  private onKeydown_(e: KeyboardEvent) {
     if (e.key === 'Enter') {
       this.onDestinationSelected_(e);
       e.stopPropagation();
@@ -181,11 +165,10 @@
   }
 
   /**
-   * @param {!Event} e Event containing the destination that was selected.
-   * @private
+   * @param e Event containing the destination that was selected.
    */
-  onDestinationSelected_(e) {
-    if (e.composedPath()[0].tagName === 'A') {
+  private onDestinationSelected_(e: Event) {
+    if ((e.composedPath()[0] as HTMLElement).tagName === 'A') {
       return;
     }
 
@@ -196,11 +179,8 @@
 
   /**
    * Returns a 1-based index for aria-rowindex.
-   * @param {number} index
-   * @return {number}
-   * @private
    */
-  getAriaRowindex_(index) {
+  private getAriaRowindex_(index: number): number {
     return index + 1;
   }
 }
diff --git a/chrome/browser/resources/print_preview/ui/destination_list_item.js b/chrome/browser/resources/print_preview/ui/destination_list_item.ts
similarity index 78%
rename from chrome/browser/resources/print_preview/ui/destination_list_item.js
rename to chrome/browser/resources/print_preview/ui/destination_list_item.ts
index f0cc8cf..28887161 100644
--- a/chrome/browser/resources/print_preview/ui/destination_list_item.js
+++ b/chrome/browser/resources/print_preview/ui/destination_list_item.ts
@@ -11,7 +11,7 @@
 import '../strings.m.js';
 
 import {assert} from 'chrome://resources/js/assert.m.js';
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
 import {loadTimeData} from 'chrome://resources/js/load_time_data.m.js';
 import {removeHighlights} from 'chrome://resources/js/search_highlight_utils.js';
 import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -24,23 +24,17 @@
 import {updateHighlights} from './highlight_utils.js';
 
 // <if expr="chromeos or lacros">
-/** @enum {number} */
-const DestinationConfigStatus = {
-  IDLE: 0,
-  IN_PROGRESS: 1,
-  FAILED: 2,
-};
+enum DestinationConfigStatus {
+  IDLE = 0,
+  IN_PROGRESS = 1,
+  FAILED = 2,
+}
 // </if>
 
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {I18nBehaviorInterface}
- */
 const PrintPreviewDestinationListItemElementBase =
-    mixinBehaviors([I18nBehavior], PolymerElement);
+    mixinBehaviors([I18nBehavior], PolymerElement) as
+    {new (): I18nBehavior & PolymerElement};
 
-/** @polymer */
 export class PrintPreviewDestinationListItemElement extends
     PrintPreviewDestinationListItemElementBase {
   static get is() {
@@ -53,29 +47,23 @@
 
   static get properties() {
     return {
-      /** @type {!Destination} */
       destination: Object,
 
-      /** @type {?RegExp} */
       searchQuery: Object,
 
-      /** @private */
       destinationIcon_: {
         type: String,
         computed: 'computeDestinationIcon_(destination, ' +
             'destination.printerStatusReason)',
       },
 
-      /** @private */
       stale_: {
         type: Boolean,
         reflectToAttribute: true,
       },
 
-      /** @private {string} */
       searchHint_: String,
 
-      /** @private */
       statusText_: {
         type: String,
         computed:
@@ -84,14 +72,12 @@
       },
 
       // <if expr="chromeos or lacros">
-      /** @private */
       isDestinationCrosLocal_: {
         type: Boolean,
         computed: 'computeIsDestinationCrosLocal_(destination)',
         reflectToAttribute: true,
       },
 
-      /** @private {!DestinationConfigStatus} */
       configurationStatus_: {
         type: Number,
         value: DestinationConfigStatus.IDLE,
@@ -99,7 +85,6 @@
 
       /**
        * Mirroring the enum so that it can be used from HTML bindings.
-       * @private
        */
       statusEnum_: {
         type: Object,
@@ -121,19 +106,26 @@
     ];
   }
 
-  constructor() {
-    super();
+  destination: Destination;
+  searchQuery: RegExp|null;
+  destinationIcon_: string;
+  private stale_: boolean;
+  private searchHint_: string;
+  private statusText_: string;
 
-    /** @private {!Array<!Node>} */
-    this.highlights_ = [];
-  }
+  // <if expr="chromeos or lacros">
+  private isDestinationCrosLocal_: boolean;
+  private configurationStatus_: DestinationConfigStatus;
+  // </if>
 
-  /** @private */
-  onDestinationPropertiesChange_() {
+  private highlights_: Node[] = [];
+
+  private onDestinationPropertiesChange_() {
     this.title = this.destination.displayName;
     this.stale_ = this.destination.isOfflineOrInvalid;
     if (this.destination.isExtension) {
-      const icon = this.shadowRoot.querySelector('.extension-icon');
+      const icon =
+          this.shadowRoot!.querySelector('.extension-icon')! as HTMLElement;
       icon.style.backgroundImage = '-webkit-image-set(' +
           'url(chrome://extension-icon/' + this.destination.extensionId +
           '/24/1) 1x,' +
@@ -157,46 +149,38 @@
 
   /**
    * Called when the printer configuration request completes.
-   * @param {boolean} success Whether configuration was successful.
+   * @param success Whether configuration was successful.
    */
-  onConfigureComplete(success) {
+  onConfigureComplete(success: boolean) {
     this.configurationStatus_ =
         success ? DestinationConfigStatus.IDLE : DestinationConfigStatus.FAILED;
   }
 
   /**
-   * @param {!DestinationConfigStatus} status
-   * @return {boolean} Whether the current configuration status is |status|.
-   * @private
+   * @return Whether the current configuration status is |status|.
    */
-  checkConfigurationStatus_(status) {
+  private checkConfigurationStatus_(status: DestinationConfigStatus): boolean {
     return this.configurationStatus_ === status;
   }
   // </if>
 
-  /** @private */
-  updateHighlightsAndHint_() {
+  private updateHighlightsAndHint_() {
     this.updateSearchHint_();
     removeHighlights(this.highlights_);
     this.highlights_ = updateHighlights(this, this.searchQuery, new Map);
   }
 
-  /** @private */
-  updateSearchHint_() {
+  private updateSearchHint_() {
     const matches = !this.searchQuery ?
         [] :
         this.destination.extraPropertiesToMatch.filter(
-            p => p.match(this.searchQuery));
+            p => p.match(this.searchQuery!));
     this.searchHint_ = matches.length === 0 ?
         (this.destination.extraPropertiesToMatch.find(p => !!p) || '') :
         matches.join(' ');
   }
 
-  /**
-   * @return {string} A tooltip for the extension printer icon.
-   * @private
-   */
-  getExtensionPrinterTooltip_() {
+  private getExtensionPrinterTooltip_(): string {
     if (!this.destination.isExtension) {
       return '';
     }
@@ -205,12 +189,11 @@
   }
 
   /**
-   * @return {string} If the destination is a local CrOS printer, this returns
+   * @return If the destination is a local CrOS printer, this returns
    *    the error text associated with the printer status. For all other
    *    printers this returns the connection status text.
-   * @private
    */
-  computeStatusText_() {
+  private computeStatusText_(): string {
     if (!this.destination) {
       return '';
     }
@@ -223,7 +206,7 @@
       }
 
       const printerStatusReason = this.destination.printerStatusReason;
-      if (!printerStatusReason ||
+      if (printerStatusReason === null ||
           printerStatusReason === PrinterStatusReason.NO_ERROR ||
           printerStatusReason === PrinterStatusReason.UNKNOWN_REASON) {
         return '';
@@ -239,11 +222,7 @@
         '';
   }
 
-  /**
-   * @return {string}
-   * @private
-   */
-  computeDestinationIcon_() {
+  private computeDestinationIcon_(): string {
     if (!this.destination) {
       return '';
     }
@@ -262,16 +241,13 @@
   // <if expr="chromeos or lacros">
   /**
    * True when the destination is a CrOS local printer.
-   * @return {boolean}
-   * @private
    */
-  computeIsDestinationCrosLocal_() {
+  private computeIsDestinationCrosLocal_(): boolean {
     return this.destination &&
         this.destination.origin === DestinationOrigin.CROS;
   }
 
-  /** @private */
-  requestPrinterStatus_() {
+  private requestPrinterStatus_() {
     // Requesting printer status only allowed for local CrOS printers.
     if (this.destination.origin !== DestinationOrigin.CROS) {
       return;
@@ -281,11 +257,7 @@
         destinationKey => this.onPrinterStatusReceived_(destinationKey));
   }
 
-  /**
-   * @param {string} destinationKey
-   * @private
-   */
-  onPrinterStatusReceived_(destinationKey) {
+  private onPrinterStatusReceived_(destinationKey: string) {
     if (this.destination.key === destinationKey) {
       // Notify printerStatusReason to trigger icon and status text update.
       this.notifyPath(`destination.printerStatusReason`);
diff --git a/chrome/browser/resources/print_preview/ui/provisional_destination_resolver.js b/chrome/browser/resources/print_preview/ui/provisional_destination_resolver.js
deleted file mode 100644
index 756628c..0000000
--- a/chrome/browser/resources/print_preview/ui/provisional_destination_resolver.js
+++ /dev/null
@@ -1,217 +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.
-
-import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
-import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
-import 'chrome://resources/cr_elements/hidden_style_css.m.js';
-import 'chrome://resources/cr_elements/shared_vars_css.m.js';
-import './print_preview_shared_css.js';
-import './print_preview_vars_css.js';
-import '../strings.m.js';
-import './throbber_css.js';
-
-import {assert} from 'chrome://resources/js/assert.m.js';
-import {I18nBehavior, I18nBehaviorInterface} from 'chrome://resources/js/i18n_behavior.m.js';
-import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
-import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-
-import {Destination} from '../data/destination.js';
-import {DestinationStore} from '../data/destination_store.js';
-
-/**
- * @fileoverview PrintPreviewProvisionalDestinationResolver
- * This class is a dialog for resolving provisional destinations. Provisional
- * destinations are extension controlled destinations that need access to a USB
- * device and have not yet been granted access by the user. Destinations are
- * resolved when the user confirms they wish to grant access and the handler
- * has successfully granted access.
- */
-
-/**
- * States that the provisional destination resolver can be in.
- * @enum {string}
- */
-const ResolverState = {
-  INITIAL: 'INITIAL',
-  ACTIVE: 'ACTIVE',
-  GRANTING_PERMISSION: 'GRANTING_PERMISSION',
-  ERROR: 'ERROR',
-  DONE: 'DONE'
-};
-
-/**
- * @constructor
- * @extends {PolymerElement}
- * @implements {I18nBehaviorInterface}
- */
-const PrintPreviewProvisionalDestinationResolverElementBase =
-    mixinBehaviors([I18nBehavior], PolymerElement);
-
-/** @polymer */
-class PrintPreviewProvisionalDestinationResolverElement extends
-    PrintPreviewProvisionalDestinationResolverElementBase {
-  static get is() {
-    return 'print-preview-provisional-destination-resolver';
-  }
-
-  static get template() {
-    return html`{__html_template__}`;
-  }
-
-  static get properties() {
-    return {
-      /** @type {?DestinationStore} */
-      destinationStore: Object,
-
-      /** @private {?Destination} */
-      destination_: {
-        type: Object,
-        value: null,
-      },
-
-      /** @private {!ResolverState} */
-      state_: {
-        type: String,
-        value: ResolverState.INITIAL,
-      },
-    };
-  }
-
-  constructor() {
-    super();
-
-    /**
-     * Promise resolver for promise returned by {@code this.resolveDestination}.
-     * @private {?PromiseResolver<!Destination>}
-     */
-    this.promiseResolver_ = null;
-  }
-
-  /** @override */
-  ready() {
-    super.ready();
-    this.addEventListener(
-        'keydown', e => this.onKeydown_(/** @type {!KeyboardEvent} */ (e)));
-  }
-
-  /**
-   * @param {!Destination} destination The destination this
-   *     dialog is needed to resolve.
-   * @return {!Promise} Promise that is resolved when the destination has been
-   *     resolved.
-   */
-  resolveDestination(destination) {
-    this.state_ = ResolverState.ACTIVE;
-    this.destination_ = destination;
-    this.$.dialog.showModal();
-    const icon = this.shadowRoot.querySelector('.extension-icon');
-    icon.style.backgroundImage = '-webkit-image-set(' +
-        'url(chrome://extension-icon/' + this.destination_.extensionId +
-        '/24/1) 1x,' +
-        'url(chrome://extension-icon/' + this.destination_.extensionId +
-        '/48/1) 2x)';
-    this.promiseResolver_ = new PromiseResolver();
-    return this.promiseResolver_.promise;
-  }
-
-  /**
-   * Handler for click on OK button. It attempts to resolve the destination.
-   * If successful, promiseResolver_.promise is resolved with the
-   * resolved destination and the dialog closes.
-   * @private
-   */
-  startResolveDestination_() {
-    assert(
-        this.state_ === ResolverState.ACTIVE,
-        'Invalid state in request grant permission');
-
-    this.state_ = ResolverState.GRANTING_PERMISSION;
-    const destination =
-        /** @type {!Destination} */ (this.destination_);
-    this.destinationStore.resolveProvisionalDestination(destination)
-        .then(
-            /** @param {?Destination} resolvedDestination */
-            (resolvedDestination) => {
-              if (this.state_ !== ResolverState.GRANTING_PERMISSION) {
-                return;
-              }
-
-              if (destination.id !== this.destination_.id) {
-                return;
-              }
-
-              if (resolvedDestination) {
-                this.state_ = ResolverState.DONE;
-                this.promiseResolver_.resolve(resolvedDestination);
-                this.promiseResolver_ = null;
-                this.$.dialog.close();
-              } else {
-                this.state_ = ResolverState.ERROR;
-              }
-            });
-  }
-
-  /**
-   * @param {!KeyboardEvent} e Event containing the key
-   * @private
-   */
-  onKeydown_(e) {
-    e.stopPropagation();
-    if (e.key === 'Escape') {
-      this.$.dialog.cancel();
-      e.preventDefault();
-    }
-  }
-
-  /** @private */
-  onCancelClick_() {
-    this.$.dialog.cancel();
-  }
-
-  /** @private */
-  onCancel_() {
-    this.promiseResolver_.reject();
-    this.state_ = ResolverState.INITIAL;
-  }
-
-  /**
-   * @return {string} The USB permission message to display.
-   * @private
-   */
-  getPermissionMessage_() {
-    return this.state_ === ResolverState.ERROR ?
-        this.i18n(
-            'resolveExtensionUSBErrorMessage',
-            this.destination_.extensionName) :
-        this.i18n('resolveExtensionUSBPermissionMessage');
-  }
-
-  /**
-   * @return {boolean} Whether the resolver is in the ERROR state.
-   * @private
-   */
-  isInErrorState_() {
-    return this.state_ === ResolverState.ERROR;
-  }
-
-  /**
-   * @return {boolean} Whether the resolver is in the ACTIVE state.
-   * @private
-   */
-  isInActiveState_() {
-    return this.state_ === ResolverState.ACTIVE;
-  }
-
-  /**
-   * @return {string} 'throbber' if the resolver is in the GRANTING_PERMISSION
-   *     state, empty otherwise.
-   */
-  getThrobberClass_() {
-    return this.state_ === ResolverState.GRANTING_PERMISSION ? 'throbber' : '';
-  }
-}
-
-customElements.define(
-    PrintPreviewProvisionalDestinationResolverElement.is,
-    PrintPreviewProvisionalDestinationResolverElement);
diff --git a/chrome/browser/resources/print_preview/ui/provisional_destination_resolver.ts b/chrome/browser/resources/print_preview/ui/provisional_destination_resolver.ts
new file mode 100644
index 0000000..9200c3af
--- /dev/null
+++ b/chrome/browser/resources/print_preview/ui/provisional_destination_resolver.ts
@@ -0,0 +1,194 @@
+// Copyright 2018 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://resources/cr_elements/cr_button/cr_button.m.js';
+import 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import 'chrome://resources/cr_elements/hidden_style_css.m.js';
+import 'chrome://resources/cr_elements/shared_vars_css.m.js';
+import './print_preview_shared_css.js';
+import './print_preview_vars_css.js';
+import '../strings.m.js';
+import './throbber_css.js';
+
+import {CrDialogElement} from 'chrome://resources/cr_elements/cr_dialog/cr_dialog.m.js';
+import {assert} from 'chrome://resources/js/assert.m.js';
+import {I18nBehavior} from 'chrome://resources/js/i18n_behavior.m.js';
+import {PromiseResolver} from 'chrome://resources/js/promise_resolver.m.js';
+import {html, mixinBehaviors, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {Destination} from '../data/destination.js';
+import {DestinationStore} from '../data/destination_store.js';
+
+/**
+ * @fileoverview PrintPreviewProvisionalDestinationResolver
+ * This class is a dialog for resolving provisional destinations. Provisional
+ * destinations are extension controlled destinations that need access to a USB
+ * device and have not yet been granted access by the user. Destinations are
+ * resolved when the user confirms they wish to grant access and the handler
+ * has successfully granted access.
+ */
+
+/**
+ * States that the provisional destination resolver can be in.
+ */
+enum ResolverState {
+  INITIAL = 'INITIAL',
+  ACTIVE = 'ACTIVE',
+  GRANTING_PERMISSION = 'GRANTING_PERMISSION',
+  ERROR = 'ERROR',
+  DONE = 'DONE'
+}
+
+export interface PrintPreviewProvisionalDestinationResolverElement {
+  $: {
+    dialog: CrDialogElement,
+  };
+}
+
+const PrintPreviewProvisionalDestinationResolverElementBase =
+    mixinBehaviors([I18nBehavior], PolymerElement) as
+    {new (): PolymerElement & I18nBehavior};
+
+export class PrintPreviewProvisionalDestinationResolverElement extends
+    PrintPreviewProvisionalDestinationResolverElementBase {
+  static get is() {
+    return 'print-preview-provisional-destination-resolver';
+  }
+
+  static get template() {
+    return html`{__html_template__}`;
+  }
+
+  static get properties() {
+    return {
+      destinationStore: Object,
+
+      destination_: {
+        type: Object,
+        value: null,
+      },
+
+      state_: {
+        type: String,
+        value: ResolverState.INITIAL,
+      },
+    };
+  }
+
+  destinationStore: DestinationStore;
+  private destination_: Destination|null;
+  private state_: ResolverState;
+  private promiseResolver_: PromiseResolver<Destination>|null = null;
+
+  ready() {
+    super.ready();
+    this.addEventListener('keydown', (e: KeyboardEvent) => this.onKeydown_(e));
+  }
+
+  /**
+   * @param destination The destination this dialog is needed to resolve.
+   * @return Promise that is resolved when the destination has been resolved.
+   */
+  resolveDestination(destination: Destination): Promise<Destination> {
+    this.state_ = ResolverState.ACTIVE;
+    this.destination_ = destination;
+    this.$.dialog.showModal();
+    const icon =
+        this.shadowRoot!.querySelector('.extension-icon')! as HTMLElement;
+    icon.style.backgroundImage = '-webkit-image-set(' +
+        'url(chrome://extension-icon/' + this.destination_!.extensionId +
+        '/24/1) 1x,' +
+        'url(chrome://extension-icon/' + this.destination_!.extensionId +
+        '/48/1) 2x)';
+    this.promiseResolver_ = new PromiseResolver();
+    return this.promiseResolver_!.promise;
+  }
+
+  /**
+   * Handler for click on OK button. It attempts to resolve the destination.
+   * If successful, promiseResolver_.promise is resolved with the
+   * resolved destination and the dialog closes.
+   */
+  private startResolveDestination_() {
+    assert(
+        this.state_ === ResolverState.ACTIVE,
+        'Invalid state in request grant permission');
+
+    this.state_ = ResolverState.GRANTING_PERMISSION;
+    const destination = this.destination_!;
+    this.destinationStore.resolveProvisionalDestination(destination)
+        .then((resolvedDestination: Destination|null) => {
+          if (this.state_ !== ResolverState.GRANTING_PERMISSION) {
+            return;
+          }
+
+          if (destination.id !== this.destination_!.id) {
+            return;
+          }
+
+          if (resolvedDestination) {
+            this.state_ = ResolverState.DONE;
+            this.promiseResolver_!.resolve(resolvedDestination!);
+            this.promiseResolver_ = null;
+            this.$.dialog.close();
+          } else {
+            this.state_ = ResolverState.ERROR;
+          }
+        });
+  }
+
+  private onKeydown_(e: KeyboardEvent) {
+    e.stopPropagation();
+    if (e.key === 'Escape') {
+      this.$.dialog.cancel();
+      e.preventDefault();
+    }
+  }
+
+  private onCancelClick_() {
+    this.$.dialog.cancel();
+  }
+
+  private onCancel_() {
+    this.promiseResolver_!.reject();
+    this.state_ = ResolverState.INITIAL;
+  }
+
+  /**
+   * @return The USB permission message to display.
+   */
+  private getPermissionMessage_(): string {
+    return this.state_ === ResolverState.ERROR ?
+        this.i18n(
+            'resolveExtensionUSBErrorMessage',
+            this.destination_!.extensionName) :
+        this.i18n('resolveExtensionUSBPermissionMessage');
+  }
+
+  /**
+   * @return Whether the resolver is in the ERROR state.
+   */
+  private isInErrorState_(): boolean {
+    return this.state_ === ResolverState.ERROR;
+  }
+
+  /**
+   * @return Whether the resolver is in the ACTIVE state.
+   */
+  private isInActiveState_(): boolean {
+    return this.state_ === ResolverState.ACTIVE;
+  }
+
+  /**
+   * @return 'throbber' if the resolver is in the GRANTING_PERMISSION state,
+   *     empty otherwise.
+   */
+  private getThrobberClass_(): string {
+    return this.state_ === ResolverState.GRANTING_PERMISSION ? 'throbber' : '';
+  }
+}
+
+customElements.define(
+    PrintPreviewProvisionalDestinationResolverElement.is,
+    PrintPreviewProvisionalDestinationResolverElement);
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
index 3498514..99dab18 100644
--- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
+++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.html
@@ -49,6 +49,12 @@
   #regulatoryInfo img {
     width: 330px;
   }
+
+  @media(prefers-color-scheme: dark) {
+    #regulatoryInfo img {
+      filter: invert(1);
+    }
+  }
 </style>
 <settings-section page-title="$i18n{aboutOsPageTitle}" section="about">
   <settings-animated-pages id="pages" section="about"
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
index 3e5837a..8c3661d 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.cc
@@ -339,7 +339,8 @@
 
 void EventReportValidator::ExpectPasswordBreachEvent(
     const std::string& expected_trigger,
-    const std::vector<std::pair<std::string, std::string>>& expected_identities,
+    const std::vector<std::pair<std::string, std::u16string>>&
+        expected_identities,
     const std::string& expected_username) {
   event_key_ = SafeBrowsingPrivateEventRouter::kKeyPasswordBreachEvent;
   trigger_ = expected_trigger;
@@ -421,13 +422,14 @@
       for (const auto& actual_identity : identities) {
         const std::string* url = actual_identity.FindStringKey(
             SafeBrowsingPrivateEventRouter::kKeyPasswordBreachIdentitiesUrl);
-        const std::string* username = actual_identity.FindStringKey(
-            SafeBrowsingPrivateEventRouter::
-                kKeyPasswordBreachIdentitiesUsername);
+        std::u16string username;
+        EXPECT_TRUE(actual_identity
+                        .FindPath(SafeBrowsingPrivateEventRouter::
+                                      kKeyPasswordBreachIdentitiesUsername)
+                        ->GetAsString(&username));
         EXPECT_NE(nullptr, url);
-        EXPECT_NE(nullptr, username);
         if (expected_identity.first == *url &&
-            expected_identity.second == *username) {
+            expected_identity.second == username) {
           matched = true;
           break;
         }
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h
index e82e8380..c937af8 100644
--- a/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h
+++ b/chrome/browser/safe_browsing/cloud_content_scanning/deep_scanning_test_utils.h
@@ -142,7 +142,7 @@
 
   void ExpectPasswordBreachEvent(
       const std::string& expected_trigger,
-      const std::vector<std::pair<std::string, std::string>>&
+      const std::vector<std::pair<std::string, std::u16string>>&
           expected_identities,
       const std::string& expected_username);
 
@@ -185,7 +185,7 @@
   std::string username_;
   absl::optional<bool> is_federated_ = absl::nullopt;
   absl::optional<std::string> federated_origin_ = absl::nullopt;
-  absl::optional<std::vector<std::pair<std::string, std::string>>>
+  absl::optional<std::vector<std::pair<std::string, std::u16string>>>
       password_breach_identities_ = absl::nullopt;
 
   // When multiple files generate events, we don't necessarily know in which
diff --git a/chrome/browser/share/share_submenu_model.cc b/chrome/browser/share/share_submenu_model.cc
index 7a445195..8f0f6c53 100644
--- a/chrome/browser/share/share_submenu_model.cc
+++ b/chrome/browser/share/share_submenu_model.cc
@@ -9,6 +9,9 @@
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/send_tab_to_self/send_tab_to_self_desktop_util.h"
+#include "chrome/browser/sharing_hub/sharing_hub_model.h"
+#include "chrome/browser/sharing_hub/sharing_hub_service.h"
+#include "chrome/browser/sharing_hub/sharing_hub_service_factory.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/qrcode_generator/qrcode_generator_bubble_controller.h"
 #include "chrome/browser/ui/send_tab_to_self/send_tab_to_self_sub_menu_model.h"
@@ -73,15 +76,18 @@
     Browser* browser,
     std::unique_ptr<ui::DataTransferEndpoint> source_endpoint,
     Context context,
-    GURL url)
+    GURL url,
+    std::u16string text)
     : ui::SimpleMenuModel(this),
       browser_(browser),
       source_endpoint_(std::move(source_endpoint)),
       context_(context),
-      url_(url) {
+      url_(url),
+      text_(text) {
   AddGenerateQRCodeItem();
   AddSendTabToSelfItem();
   AddCopyLinkItem();
+  AddShareToThirdPartyItems();
 }
 
 ShareSubmenuModel::~ShareSubmenuModel() = default;
@@ -98,6 +104,9 @@
     case IDC_CONTENT_CONTEXT_COPYIMAGELOCATION:
       CopyLink();
       break;
+    default:
+      ShareToThirdParty(id);
+      break;
   }
 }
 
@@ -171,6 +180,33 @@
   }
 }
 
+void ShareSubmenuModel::AddShareToThirdPartyItems() {
+  auto* model = GetSharingHubModel();
+  if (!model)
+    return;
+
+  // TODO(https://crbug.com/1252160): Support 3P items for link and image
+  // targets.
+  if (context_ == Context::IMAGE || context_ == Context::LINK)
+    return;
+
+  AddSeparator(ui::MenuSeparatorType::NORMAL_SEPARATOR);
+  AddItemWithStringId(0, IDS_SHARING_HUB_SHARE_LABEL);
+  SetEnabledAt(GetItemCount() - 1, false);
+
+  std::vector<sharing_hub::SharingHubAction> actions;
+  model->GetThirdPartyActionList(&actions);
+
+  for (const auto& action : actions) {
+    auto image = ui::ImageModel::FromImageSkia(action.third_party_icon);
+    AddItemWithIcon(action.command_id, action.title, image);
+    SetAccessibleNameAt(
+        GetItemCount() - 1,
+        l10n_util::GetStringFUTF16(IDS_SHARING_HUB_SHARE_LABEL_ACCESSIBILITY,
+                                   action.title));
+  }
+}
+
 void ShareSubmenuModel::AddSendTabToSelfSingleTargetItem() {
   std::u16string label = l10n_util::GetStringFUTF16(
       IDS_LINK_MENU_SEND_TAB_TO_SELF_SINGLE_TARGET,
@@ -225,4 +261,21 @@
   scw.WriteText(FormatURLForClipboard(url_));
 }
 
+void ShareSubmenuModel::ShareToThirdParty(int id) {
+  auto* model = GetSharingHubModel();
+  DCHECK(model);
+
+  model->ExecuteThirdPartyAction(browser_->profile(), url_, text_, id);
+}
+
+sharing_hub::SharingHubModel* ShareSubmenuModel::GetSharingHubModel() {
+  // Allowed in unit tests.
+  if (!browser_)
+    return nullptr;
+
+  sharing_hub::SharingHubService* const service =
+      sharing_hub::SharingHubServiceFactory::GetForProfile(browser_->profile());
+  return service ? service->GetSharingHubModel() : nullptr;
+}
+
 }  // namespace share
diff --git a/chrome/browser/share/share_submenu_model.h b/chrome/browser/share/share_submenu_model.h
index 9ccb8605..87226423 100644
--- a/chrome/browser/share/share_submenu_model.h
+++ b/chrome/browser/share/share_submenu_model.h
@@ -16,6 +16,10 @@
 class SendTabToSelfSubMenuModel;
 }
 
+namespace sharing_hub {
+class SharingHubModel;
+}
+
 namespace share {
 
 extern const base::Feature kShareMenu;
@@ -46,11 +50,13 @@
   // The |url| parameter is a bit tricky: it is the "target URL" of the
   // containing menu, whatever that happens to be. The exact meaning of that
   // depends on |context|. The |source_endpoint| is the source of |url| or
-  // whichever other data is being offered for share (image or similar).
+  // whichever other data is being offered for share (image or similar), and
+  // |text| is text describing the data being shared.
   ShareSubmenuModel(Browser* browser,
                     std::unique_ptr<ui::DataTransferEndpoint> source_endpoint,
                     Context context,
-                    GURL url);
+                    GURL url,
+                    std::u16string text);
   ~ShareSubmenuModel() override;
 
   // ui::SimpleMenuModel::Delegate:
@@ -60,17 +66,22 @@
   void AddGenerateQRCodeItem();
   void AddSendTabToSelfItem();
   void AddCopyLinkItem();
+  void AddShareToThirdPartyItems();
 
   void AddSendTabToSelfSingleTargetItem();
 
   void GenerateQRCode();
   void SendTabToSelfSingleTarget();
   void CopyLink();
+  void ShareToThirdParty(int command_id);
+
+  sharing_hub::SharingHubModel* GetSharingHubModel();
 
   Browser* browser_;
   std::unique_ptr<ui::DataTransferEndpoint> source_endpoint_;
   Context context_;
   GURL url_;
+  std::u16string text_;
 
   std::unique_ptr<send_tab_to_self::SendTabToSelfSubMenuModel>
       stts_submenu_model_;
diff --git a/chrome/browser/share/share_submenu_model_unittest.cc b/chrome/browser/share/share_submenu_model_unittest.cc
index adadd79..9ac8c21 100644
--- a/chrome/browser/share/share_submenu_model_unittest.cc
+++ b/chrome/browser/share/share_submenu_model_unittest.cc
@@ -25,19 +25,19 @@
 
 TEST(ShareSubmenuModelTest, CopyItemPresentForLink) {
   ShareSubmenuModel model(nullptr, nullptr, ShareSubmenuModel::Context::LINK,
-                          GURL("https://www.chromium.org"));
+                          GURL("https://www.chromium.org"), u"");
   EXPECT_TRUE(HasItemWithName(model, IDS_CONTENT_CONTEXT_COPYLINKLOCATION));
 }
 
 TEST(ShareSubmenuModelTest, CopyItemPresentForImage) {
   ShareSubmenuModel model(nullptr, nullptr, ShareSubmenuModel::Context::IMAGE,
-                          GURL("https://www.chromium.org/image.png"));
+                          GURL("https://www.chromium.org/image.png"), u"");
   EXPECT_TRUE(HasItemWithName(model, IDS_CONTENT_CONTEXT_COPYIMAGELOCATION));
 }
 
 TEST(ShareSubmenuModelTest, CopyItemPresentForEmail) {
   ShareSubmenuModel model(nullptr, nullptr, ShareSubmenuModel::Context::LINK,
-                          GURL("mailto:example@chromium.org"));
+                          GURL("mailto:example@chromium.org"), u"");
   EXPECT_TRUE(HasItemWithName(model, IDS_CONTENT_CONTEXT_COPYEMAILADDRESS));
 }
 
diff --git a/chrome/browser/sharing/proto/BUILD.gn b/chrome/browser/sharing/proto/BUILD.gn
index e2bc2378..3cab9b5f 100644
--- a/chrome/browser/sharing/proto/BUILD.gn
+++ b/chrome/browser/sharing/proto/BUILD.gn
@@ -11,6 +11,7 @@
 proto_library("proto") {
   sources = [
     "click_to_call_message.proto",
+    "optimization_guide_push_notification.proto",
     "peer_connection_messages.proto",
     "remote_copy_message.proto",
     "shared_clipboard_message.proto",
diff --git a/chrome/browser/sharing/proto/optimization_guide_push_notification.proto b/chrome/browser/sharing/proto/optimization_guide_push_notification.proto
new file mode 100644
index 0000000..a5cb1b9b
--- /dev/null
+++ b/chrome/browser/sharing/proto/optimization_guide_push_notification.proto
@@ -0,0 +1,20 @@
+// Copyright 2021 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.
+
+syntax = "proto3";
+
+option java_multiple_files = true;
+option java_package = "org.chromium.chrome.browser.sharing.proto";
+
+package chrome_browser_sharing;
+
+// Required in Chrome.
+option optimize_for = LITE_RUNTIME;
+
+// Message used to deliver push notifications through optimization guide.
+// Next tag: 2
+message OptimizationGuidePushNotification {
+  // This is a HintNotificationPayload.
+  bytes hint_notification_payload_bytes = 1;
+}
diff --git a/chrome/browser/sharing/proto/sharing_message.proto b/chrome/browser/sharing/proto/sharing_message.proto
index 51676df..b437aea 100644
--- a/chrome/browser/sharing/proto/sharing_message.proto
+++ b/chrome/browser/sharing/proto/sharing_message.proto
@@ -8,6 +8,7 @@
 option java_package = "org.chromium.chrome.browser.sharing.proto";
 
 import "click_to_call_message.proto";
+import "optimization_guide_push_notification.proto";
 import "peer_connection_messages.proto";
 import "remote_copy_message.proto";
 import "shared_clipboard_message.proto";
@@ -34,10 +35,11 @@
   PEER_CONNECTION_ICE_CANDIDATES_MESSAGE = 8;
   DISCOVERY_REQUEST = 9;
   WEB_RTC_SIGNALING_FRAME = 10;
+  OPTIMIZATION_GUIDE_PUSH_NOTIFICATION = 11;
 }
 
 // Message for sending between devices in Sharing.
-// Next tag: 16
+// Next tag: 17
 message SharingMessage {
   // Identifier of sender. required unless any of the following is true:
   // 1. payload is a AckMessage
@@ -57,6 +59,7 @@
         11;
     DiscoveryRequest discovery_request = 13;
     WebRtcSignalingMessage web_rtc_signaling_frame = 14;
+    OptimizationGuidePushNotification optimization_guide_push_notification = 16;
   }
 
   oneof ack_channel_configuration {
diff --git a/chrome/browser/sharing/sharing_metrics.cc b/chrome/browser/sharing/sharing_metrics.cc
index d2268ac..7e9d41a 100644
--- a/chrome/browser/sharing/sharing_metrics.cc
+++ b/chrome/browser/sharing/sharing_metrics.cc
@@ -140,6 +140,9 @@
       return chrome_browser_sharing::DISCOVERY_REQUEST;
     case chrome_browser_sharing::SharingMessage::kWebRtcSignalingFrame:
       return chrome_browser_sharing::WEB_RTC_SIGNALING_FRAME;
+    case chrome_browser_sharing::SharingMessage::
+        kOptimizationGuidePushNotification:
+      return chrome_browser_sharing::OPTIMIZATION_GUIDE_PUSH_NOTIFICATION;
   }
   // For proto3 enums unrecognized enum values are kept when parsing, and a new
   // payload case received over the network would not default to
diff --git a/chrome/browser/sharing_hub/sharing_hub_model.cc b/chrome/browser/sharing_hub/sharing_hub_model.cc
index d4f074f8..314c4b5 100644
--- a/chrome/browser/sharing_hub/sharing_hub_model.cc
+++ b/chrome/browser/sharing_hub/sharing_hub_model.cc
@@ -96,19 +96,17 @@
 }
 
 void SharingHubModel::GetThirdPartyActionList(
-    content::WebContents* web_contents,
     std::vector<SharingHubAction>* list) {
   for (const auto& action : third_party_action_list_) {
     list->push_back(action);
   }
 }
 
-void SharingHubModel::ExecuteThirdPartyAction(
-    content::WebContents* web_contents,
-    int id) {
-  const std::string& url = web_contents->GetLastCommittedURL().spec();
-  const std::u16string& title = web_contents->GetTitle();
-
+void SharingHubModel::ExecuteThirdPartyAction(Profile* profile,
+                                              const GURL& gurl,
+                                              const std::u16string& title,
+                                              int id) {
+  const std::string url = gurl.spec();
   auto url_it = third_party_action_urls_.find(id);
   if (url_it == third_party_action_urls_.end())
     return;
@@ -132,9 +130,7 @@
 
   GURL share_url = GURL(url_found);
   if (share_url.is_valid()) {
-    NavigateParams params(
-        Profile::FromBrowserContext(web_contents->GetBrowserContext()),
-        share_url, ui::PAGE_TRANSITION_LINK);
+    NavigateParams params(profile, share_url, ui::PAGE_TRANSITION_LINK);
     params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
     Navigate(&params);
     base::RecordAction(
@@ -144,6 +140,13 @@
   }
 }
 
+void SharingHubModel::ExecuteThirdPartyAction(content::WebContents* contents,
+                                              int id) {
+  ExecuteThirdPartyAction(
+      Profile::FromBrowserContext(contents->GetBrowserContext()),
+      contents->GetLastCommittedURL(), contents->GetTitle(), id);
+}
+
 void SharingHubModel::PopulateFirstPartyActions() {
   first_party_action_list_.push_back(
       {IDC_COPY_URL, l10n_util::GetStringUTF16(IDS_SHARING_HUB_COPY_LINK_LABEL),
diff --git a/chrome/browser/sharing_hub/sharing_hub_model.h b/chrome/browser/sharing_hub/sharing_hub_model.h
index 9d19dc8..504c3e9 100644
--- a/chrome/browser/sharing_hub/sharing_hub_model.h
+++ b/chrome/browser/sharing_hub/sharing_hub_model.h
@@ -14,6 +14,7 @@
 #include "ui/gfx/image/image_skia.h"
 
 class GURL;
+class Profile;
 
 namespace sharing {
 namespace mojom {
@@ -69,12 +70,19 @@
                                std::vector<SharingHubAction>* list);
   // Populates the vector with third party Sharing Hub actions, ordered by
   // appearance in the dialog.
-  void GetThirdPartyActionList(content::WebContents* web_contents,
-                               std::vector<SharingHubAction>* list);
+  void GetThirdPartyActionList(std::vector<SharingHubAction>* list);
 
   // Executes the third party action indicated by |id|, i.e. opens a popup to
-  // the corresponding webpage.
-  void ExecuteThirdPartyAction(content::WebContents* web_contents, int id);
+  // the corresponding webpage. The |url| is the URL to share, and the |title|
+  // is the title (if there is one) of the shared URL.
+  void ExecuteThirdPartyAction(Profile* profile,
+                               const GURL& url,
+                               const std::u16string& title,
+                               int id);
+
+  // Convenience wrapper around the above when sharing a WebContents. This
+  // extracts the title and URL to share from the provided WebContents.
+  void ExecuteThirdPartyAction(content::WebContents* contents, int id);
 
   // sharing::ShareTargetsObserver implementation.
   void OnShareTargetsUpdated(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index adcc7abc..fcb01dc2 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -2230,6 +2230,8 @@
       "views/crostini/crostini_ansible_software_config_view.h",
       "views/crostini/crostini_app_restart_dialog.cc",
       "views/crostini/crostini_app_restart_dialog.h",
+      "views/crostini/crostini_expired_container_warning_view.cc",
+      "views/crostini/crostini_expired_container_warning_view.h",
       "views/crostini/crostini_force_close_view.cc",
       "views/crostini/crostini_force_close_view.h",
       "views/crostini/crostini_package_install_failure_view.cc",
diff --git a/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_medium_layout.xml b/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_medium_layout.xml
index 9ea3d59f..6188abe7 100644
--- a/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_medium_layout.xml
+++ b/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_medium_layout.xml
@@ -5,7 +5,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/quick_action_widget"
-    android:layout_width="@dimen/quick_action_search_widget_width"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/quick_action_search_widget_background"
     android:orientation="vertical">
diff --git a/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_small_layout.xml b/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_small_layout.xml
index bd8cfb00..62adf23b 100644
--- a/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_small_layout.xml
+++ b/chrome/browser/ui/android/quickactionsearchwidget/java/res/layout/quick_action_search_widget_small_layout.xml
@@ -5,7 +5,7 @@
 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/quick_action_widget_small"
-    android:layout_width="@dimen/quick_action_search_widget_width"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:background="@drawable/quick_action_search_widget_background"
     android:baselineAligned="false"
diff --git a/chrome/browser/ui/android/quickactionsearchwidget/java/res/values/dimens.xml b/chrome/browser/ui/android/quickactionsearchwidget/java/res/values/dimens.xml
index ee410b2e..6eb95117 100644
--- a/chrome/browser/ui/android/quickactionsearchwidget/java/res/values/dimens.xml
+++ b/chrome/browser/ui/android/quickactionsearchwidget/java/res/values/dimens.xml
@@ -4,7 +4,7 @@
      found in the LICENSE file. -->
 
 <resources xmlns:tools="http://schemas.android.com/tools">
-    <dimen name="quick_action_search_widget_width">308dp</dimen>
+    <dimen name="quick_action_search_widget_width">240dp</dimen>
     <dimen name="quick_action_search_widget_background_radius">16dp</dimen>
     <dimen name="quick_action_search_widget_button_container_margin">12dp</dimen>
     <dimen name="quick_action_search_widget_button_margin">4dp</dimen>
diff --git a/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_medium_info.xml b/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_medium_info.xml
index 06cfc48..f152b9e 100644
--- a/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_medium_info.xml
+++ b/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_medium_info.xml
@@ -8,5 +8,5 @@
     android:minWidth="@dimen/quick_action_search_widget_width"
     android:minHeight="@dimen/quick_action_search_widget_medium_height"
     android:previewImage="@drawable/quick_action_search_widget_medium_preview"
-    android:resizeMode="none"
+    android:resizeMode="horizontal"
     android:widgetCategory="home_screen|searchbox" />
diff --git a/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_small_info.xml b/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_small_info.xml
index 685b1e80..1005f7e 100644
--- a/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_small_info.xml
+++ b/chrome/browser/ui/android/quickactionsearchwidget/java/res/xml/quick_action_search_widget_small_info.xml
@@ -7,6 +7,6 @@
     android:initialLayout="@layout/quick_action_search_widget_small_layout"
     android:minWidth="@dimen/quick_action_search_widget_width"
     android:minHeight="@dimen/quick_action_search_widget_small_height"
-    android:resizeMode="none"
+    android:resizeMode="horizontal"
     android:previewImage="@drawable/quick_action_search_widget_small_preview"
     android:widgetCategory="home_screen|searchbox" />
diff --git a/chrome/browser/ui/app_list/app_list_model_updater.h b/chrome/browser/ui/app_list/app_list_model_updater.h
index da58bab3..34ecad7 100644
--- a/chrome/browser/ui/app_list/app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/app_list_model_updater.h
@@ -78,7 +78,7 @@
                                const syncer::StringOrdinal& new_position) {}
   virtual void SetItemIsPersistent(const std::string& id, bool is_persistent) {}
   virtual void SetItemFolderId(const std::string& id,
-                               const std::string& folder_id) {}
+                               const std::string& folder_id) = 0;
   virtual void SetNotificationBadgeColor(const std::string& id,
                                          const SkColor color) {}
 
diff --git a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
index d153a9d..33a72100 100644
--- a/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
+++ b/chrome/browser/ui/app_list/app_list_syncable_service_unittest.cc
@@ -913,7 +913,7 @@
   ASSERT_FALSE(model_updater()->FindItem(kChildItemId2));
 
   // Move the child_item_1 out of the folder.
-  child_item_1->SetFolderId("");
+  model_updater()->SetItemFolderId(child_item_1->id(), "");
   model_updater()->OnItemUpdated(child_item_1->CloneMetadata());
 
   // Verify both child item are moved out of the folder.
diff --git a/chrome/browser/ui/app_list/chrome_app_list_item.cc b/chrome/browser/ui/app_list/chrome_app_list_item.cc
index dc38e93..20ba1d96 100644
--- a/chrome/browser/ui/app_list/chrome_app_list_item.cc
+++ b/chrome/browser/ui/app_list/chrome_app_list_item.cc
@@ -210,9 +210,6 @@
 
 void ChromeAppListItem::SetFolderId(const std::string& folder_id) {
   metadata_->folder_id = folder_id;
-  AppListModelUpdater* updater = model_updater();
-  if (updater)
-    updater->SetItemFolderId(id(), folder_id);
 }
 
 void ChromeAppListItem::SetPosition(const syncer::StringOrdinal& position) {
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
index 9065449..61016ff2 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.cc
@@ -75,6 +75,11 @@
   }
 }
 
+void FakeAppListModelUpdater::SetItemFolderId(const std::string& id,
+                                              const std::string& folder_id) {
+  FindItem(id)->SetFolderId(folder_id);
+}
+
 void FakeAppListModelUpdater::SetSearchEngineIsGoogle(bool is_google) {
   search_engine_is_google_ = is_google;
 }
diff --git a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
index 25b3ce8..7098e16 100644
--- a/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
+++ b/chrome/browser/ui/app_list/test/fake_app_list_model_updater.h
@@ -41,6 +41,8 @@
   void MoveItemToFolder(const std::string& id,
                         const std::string& folder_id) override;
   void SetItemIcon(const std::string& id, const gfx::ImageSkia& icon) override;
+  void SetItemFolderId(const std::string& id,
+                       const std::string& folder_id) override;
   // For SearchModel:
   void SetSearchEngineIsGoogle(bool is_google) override;
   void PublishSearchResults(
diff --git a/chrome/browser/ui/ash/clipboard_history_browsertest.cc b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
index 29b5b9a..edb5564 100644
--- a/chrome/browser/ui/ash/clipboard_history_browsertest.cc
+++ b/chrome/browser/ui/ash/clipboard_history_browsertest.cc
@@ -1178,11 +1178,9 @@
                       content::RenderFrameHost* rfh,
                       base::OnceCallback<void(bool)> callback) override {}
 
-  bool IsDragDropAllowed(const ui::DataTransferEndpoint* const data_src,
-                         const ui::DataTransferEndpoint* const data_dst,
-                         const bool is_drop) override {
-    return false;
-  }
+  void DropIfAllowed(const ui::DataTransferEndpoint* data_src,
+                     const ui::DataTransferEndpoint* data_dst,
+                     base::OnceClosure drop_cb) override {}
 
  private:
   const url::Origin allowed_origin_;
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc b/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc
index 65ef80f..73984e9 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_client_impl_browsertest.cc
@@ -150,8 +150,7 @@
 }
 
 // Verifies that `HoldingSpaceClient::OpenDownloads()` works as intended.
-// TODO(crbug.com/1139299): Flaky.
-IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, DISABLED_OpenDownloads) {
+IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, OpenDownloads) {
   ASSERT_TRUE(HoldingSpaceController::Get());
 
   auto* holding_space_client = HoldingSpaceController::Get()->client();
@@ -253,13 +252,7 @@
 // Verifies that `HoldingSpaceClient::ShowItemInFolder()` works as intended when
 // attempting to open holding space items backed by both non-existing and
 // existing files.
-// Flaky on linux-chromeos-dbg (https://crbug.com/1130958)
-#ifdef NDEBUG
-#define MAYBE_ShowItemInFolder ShowItemInFolder
-#else
-#define MAYBE_ShowItemInFolder DISABLED_ShowItemInFolder
-#endif
-IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, MAYBE_ShowItemInFolder) {
+IN_PROC_BROWSER_TEST_F(HoldingSpaceClientImplTest, ShowItemInFolder) {
   ASSERT_TRUE(HoldingSpaceController::Get());
 
   auto* holding_space_client = HoldingSpaceController::Get()->client();
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
index 02472db..54c4765d 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.cc
@@ -267,8 +267,10 @@
 }
 
 const std::string& HoldingSpaceKeyedService::AddPhoneHubCameraRollItem(
-    const base::FilePath& item_path) {
-  return AddItemOfType(HoldingSpaceItem::Type::kPhoneHubCameraRoll, item_path);
+    const base::FilePath& item_path,
+    const HoldingSpaceProgress& progress) {
+  return AddItemOfType(HoldingSpaceItem::Type::kPhoneHubCameraRoll, item_path,
+                       progress);
 }
 
 const std::string& HoldingSpaceKeyedService::AddItem(
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
index 5d03516..8a77a5f 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service.h
@@ -116,7 +116,9 @@
   // Adds a photo or video downloaded from a connected Android phone via
   // PhoneHub. Returns the id of the added holding space item or an empty string
   // if the item was not added due to de-duplication checks.
-  const std::string& AddPhoneHubCameraRollItem(const base::FilePath& item_path);
+  const std::string& AddPhoneHubCameraRollItem(
+      const base::FilePath& item_path,
+      const HoldingSpaceProgress& progress);
 
   // Adds the specified `item` to the holding space model. Returns the id of the
   // added holding space item or an empty string if the item was not added due
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
index 4e3e3374..1afd45b 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_keyed_service_unittest.cc
@@ -25,6 +25,7 @@
 #include "base/test/bind.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/simple_test_clock.h"
+#include "base/time/time_override.h"
 #include "chrome/browser/ash/file_manager/app_id.h"
 #include "chrome/browser/ash/file_manager/fake_disk_mount_manager.h"
 #include "chrome/browser/ash/file_manager/fileapi_util.h"
@@ -301,7 +302,9 @@
 class HoldingSpaceKeyedServiceTest : public BrowserWithTestWindowTest {
  public:
   HoldingSpaceKeyedServiceTest()
-      : fake_user_manager_(new FakeChromeUserManager),
+      : BrowserWithTestWindowTest(
+            base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+        fake_user_manager_(new FakeChromeUserManager),
         user_manager_enabler_(base::WrapUnique(fake_user_manager_)) {
     HoldingSpaceImage::SetUseZeroInvalidationDelayForTesting(true);
   }
@@ -316,11 +319,16 @@
 
   // BrowserWithTestWindowTest:
   void SetUp() override {
+    // The test's task environment starts with a mock time close to the Unix
+    // epoch, but the files that back holding space items are created with
+    // accurate timestamps. Advance the clock so that the test's mock time and
+    // the time used for file operations are in sync for file age calculations.
+    task_environment()->AdvanceClock(base::subtle::TimeNowIgnoringOverride() -
+                                     base::Time::Now());
     // Needed by `file_manager::VolumeManager`.
     chromeos::disks::DiskMountManager::InitializeForTesting(
         new file_manager::FakeDiskMountManager);
     BrowserWithTestWindowTest::SetUp();
-    holding_space_util::SetNowForTesting(absl::nullopt);
   }
 
   void TearDown() override {
@@ -1583,8 +1591,8 @@
   EXPECT_EQ(file_path_2, holding_space_model->items()[0]->file_path());
 }
 
-// Verifies that screenshots restored from persistence are not older than
-// kMaxFileAge.
+// Verifies that files restored from persistence are not older than
+// `kMaxFileAge`.
 TEST_F(HoldingSpaceKeyedServiceTest, RemoveOlderFilesFromPersistence) {
   // Create file system mount point.
   std::unique_ptr<ScopedTestMountPoint> downloads_mount =
@@ -1597,6 +1605,7 @@
   HoldingSpaceModel::ItemList restored_holding_space_items;
   base::Value persisted_holding_space_items_after_restoration(
       base::Value::Type::LIST);
+  base::Time last_creation_time = base::Time::Now();
 
   // Create a secondary profile w/ a pre-populated pref store.
   TestingProfile* const secondary_profile = CreateSecondaryProfile(
@@ -1621,7 +1630,8 @@
 
           // Only pinned files are exempt from age checks. In this test, we
           // expect all holding space items of other types to be removed from
-          // persistence during restoration due to being older than kMaxFileAge.
+          // persistence during restoration due to being older than
+          // `kMaxFileAge`.
           if (type == HoldingSpaceItem::Type::kPinnedFile) {
             persisted_holding_space_items_after_restoration.Append(
                 fresh_holding_space_item->Serialize());
@@ -1629,20 +1639,9 @@
                 std::move(fresh_holding_space_item));
           }
 
-          const base::FilePath stale_item_file =
-              downloads_mount->GetRootPath().AppendASCII(
-                  base::UnguessableToken::Create().ToString());
-          auto stale_holding_space_item =
-              HoldingSpaceItem::CreateFileBackedItem(
-                  type, stale_item_file,
-                  GetFileSystemUrl(GetProfile(), stale_item_file),
-                  base::BindOnce(&CreateTestHoldingSpaceImage));
-
-          // NOTE: While the `stale_holding_space_item` is persisted here, we do
-          // *not* expect it to be restored or to be persisted after model
-          // restoration since its backing file does *not* exist.
-          persisted_holding_space_items_before_restoration.Append(
-              stale_holding_space_item->Serialize());
+          base::File::Info file_info;
+          ASSERT_TRUE(base::GetFileInfo(file, &file_info));
+          last_creation_time = file_info.creation_time;
         }
 
         pref_store->SetValueSilently(
@@ -1652,7 +1651,10 @@
             PersistentPrefStore::DEFAULT_PREF_WRITE_FLAGS);
       }));
 
-  holding_space_util::SetNowForTesting(base::Time::Now() + kMaxFileAge);
+  // Fast-forward to a point where the created files are too old to be restored
+  // from persistence.
+  task_environment()->FastForwardBy(last_creation_time - base::Time::Now() +
+                                    kMaxFileAge);
 
   ActivateSecondaryProfile();
   HoldingSpaceModelAttachedWaiter(secondary_profile).Wait();
@@ -2273,9 +2275,11 @@
         holding_space_service->AddScreenshot(file_path);
         break;
       case HoldingSpaceItem::Type::kPhoneHubCameraRoll:
-        EXPECT_EQ(holding_space_model->ContainsItem(type, file_path),
-                  holding_space_service->AddPhoneHubCameraRollItem(file_path)
-                      .empty());
+        EXPECT_EQ(
+            holding_space_model->ContainsItem(type, file_path),
+            holding_space_service
+                ->AddPhoneHubCameraRollItem(file_path, HoldingSpaceProgress())
+                .empty());
         break;
     }
   }
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc b/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc
index ab2a341..e8d7844 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_ui_browsertest.cc
@@ -23,6 +23,7 @@
 #include "ash/public/cpp/holding_space/mock_holding_space_client.h"
 #include "ash/public/cpp/holding_space/mock_holding_space_model_observer.h"
 #include "ash/test/view_drawn_waiter.h"
+#include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/containers/contains.h"
 #include "base/files/file_util.h"
@@ -411,8 +412,19 @@
 
   ui::mojom::DragOperation OnPerformDrop(
       const ui::DropTargetEvent& event) override {
+    ui::mojom::DragOperation output_drag_op = ui::mojom::DragOperation::kNone;
+    PerformDrop(event, output_drag_op);
+    return output_drag_op;
+  }
+
+  DropCallback GetDropCallback(const ui::DropTargetEvent& event) override {
+    return base::BindOnce(&DropTargetView::PerformDrop, base::Unretained(this));
+  }
+
+  void PerformDrop(const ui::DropTargetEvent& event,
+                   ui::mojom::DragOperation& output_drag_op) {
     EXPECT_TRUE(event.data().GetFilename(&copied_file_path_));
-    return ui::mojom::DragOperation::kCopy;
+    output_drag_op = ui::mojom::DragOperation::kCopy;
   }
 
   void InitWidget(aura::Window* context) {
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_util.cc b/chrome/browser/ui/ash/holding_space/holding_space_util.cc
index fb295d7..ec4bbf1 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_util.cc
+++ b/chrome/browser/ui/ash/holding_space/holding_space_util.cc
@@ -21,12 +21,6 @@
 namespace ash {
 namespace holding_space_util {
 
-namespace {
-
-absl::optional<base::Time> now_for_testing;
-
-}  // namespace
-
 ValidityRequirement::ValidityRequirement() = default;
 ValidityRequirement::ValidityRequirement(const ValidityRequirement&) = default;
 ValidityRequirement::ValidityRequirement(ValidityRequirement&& other) = default;
@@ -47,9 +41,9 @@
             if (requirement.must_exist)
               valid = result == base::File::Error::FILE_OK;
             if (valid && requirement.must_be_newer_than) {
-              valid = file_info.creation_time >
-                      now_for_testing.value_or(base::Time::Now()) -
-                          requirement.must_be_newer_than.value();
+              valid =
+                  file_info.creation_time >
+                  base::Time::Now() - requirement.must_be_newer_than.value();
             }
             std::move(callback).Run(valid);
           },
@@ -207,9 +201,5 @@
           placeholder_image_skia_resolver));
 }
 
-void SetNowForTesting(absl::optional<base::Time> now) {
-  now_for_testing = now;
-}
-
 }  // namespace holding_space_util
 }  // namespace ash
diff --git a/chrome/browser/ui/ash/holding_space/holding_space_util.h b/chrome/browser/ui/ash/holding_space/holding_space_util.h
index 3734f6b..dbb60c2 100644
--- a/chrome/browser/ui/ash/holding_space/holding_space_util.h
+++ b/chrome/browser/ui/ash/holding_space/holding_space_util.h
@@ -88,8 +88,6 @@
     HoldingSpaceItem::Type type,
     const base::FilePath& file_path);
 
-void SetNowForTesting(absl::optional<base::Time> now);
-
 }  // namespace holding_space_util
 }  // namespace ash
 
diff --git a/chrome/browser/ui/hats/hats_service.cc b/chrome/browser/ui/hats/hats_service.cc
index 15707a3..d8e9df02 100644
--- a/chrome/browser/ui/hats/hats_service.cc
+++ b/chrome/browser/ui/hats/hats_service.cc
@@ -43,6 +43,9 @@
     "ts-trusted-surface";
 constexpr char kHatsSurveyTriggerTrustSafetyTransactions[] = "ts-transactions";
 constexpr char kHatsSurveyTriggerAccuracyTips[] = "accuracy-tips";
+constexpr char kHatsSurveyTriggerAutofillAddress[] = "autofill-address";
+constexpr char kHatsSurveyTriggerAutofillCard[] = "autofill-card";
+constexpr char kHatsSurveyTriggerAutofillPassword[] = "autofill-password";
 
 constexpr char kHatsNextSurveyTriggerIDTesting[] =
     "HLpeYy5Av0ugnJ3q1cK0XzzA8UHv";
@@ -169,6 +172,14 @@
       /*presupplied_trigger_id=*/absl::nullopt, std::vector<std::string>{},
       std::vector<std::string>{"Tip shown for URL", "UI interaction"});
 
+  // Autofill surveys.
+  survey_configs.emplace_back(&features::kAutofillAddressSurvey,
+                              kHatsSurveyTriggerAutofillAddress);
+  survey_configs.emplace_back(&features::kAutofillCardSurvey,
+                              kHatsSurveyTriggerAutofillCard);
+  survey_configs.emplace_back(&features::kAutofillPasswordSurvey,
+                              kHatsSurveyTriggerAutofillPassword);
+
   return survey_configs;
 }
 
diff --git a/chrome/browser/ui/hats/hats_service.h b/chrome/browser/ui/hats/hats_service.h
index 631009e..3887615 100644
--- a/chrome/browser/ui/hats/hats_service.h
+++ b/chrome/browser/ui/hats/hats_service.h
@@ -50,6 +50,9 @@
 extern const char kHatsSurveyTriggerTrustSafetyTrustedSurface[];
 extern const char kHatsSurveyTriggerTrustSafetyTransactions[];
 extern const char kHatsSurveyTriggerAccuracyTips[];
+extern const char kHatsSurveyTriggerAutofillAddress[];
+extern const char kHatsSurveyTriggerAutofillCard[];
+extern const char kHatsSurveyTriggerAutofillPassword[];
 
 // The Trigger ID for a test HaTS Next survey which is available for testing
 // and demo purposes when the migration feature flag is enabled.
diff --git a/chrome/browser/ui/hung_renderer/hung_renderer_core.cc b/chrome/browser/ui/hung_renderer/hung_renderer_core.cc
index f42dcc1..4f6fb9a 100644
--- a/chrome/browser/ui/hung_renderer/hung_renderer_core.cc
+++ b/chrome/browser/ui/hung_renderer/hung_renderer_core.cc
@@ -31,26 +31,44 @@
 // process.
 bool IsWebContentsHung(content::WebContents* web_contents,
                        content::RenderProcessHost* hung_process) {
-  for (auto* frame : web_contents->GetAllFrames()) {
-    if (frame->GetProcess() == hung_process)
-      return true;
-  }
-  return false;
+  bool result = false;
+  // We only consider frames visible to the user for hung frames. This is
+  // fine because only frames receiving input are considered hung.
+  web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
+      [](const content::RenderProcessHost* hung_process, bool* result,
+         content::RenderFrameHost* render_frame_host) {
+        if (render_frame_host->GetProcess() == hung_process) {
+          *result = true;
+          return content::RenderFrameHost::FrameIterationAction::kStop;
+        }
+        return content::RenderFrameHost::FrameIterationAction::kContinue;
+      },
+      hung_process, &result));
+  return result;
 }
 
 // Returns the URL of the first hung frame encountered in the WebContents.
 GURL GetURLOfAnyHungFrame(content::WebContents* web_contents,
                           content::RenderProcessHost* hung_process) {
-  for (auto* frame : web_contents->GetAllFrames()) {
-    if (frame->GetProcess() == hung_process)
-      return frame->GetLastCommittedURL();
-  }
+  GURL result;
+  // We only consider frames visible to the user for hung frames. This is
+  // fine because only frames receiving input are considered hung.
+  web_contents->GetMainFrame()->ForEachRenderFrameHost(base::BindRepeating(
+      [](const content::RenderProcessHost* hung_process, GURL* result,
+         content::RenderFrameHost* render_frame_host) {
+        if (render_frame_host->GetProcess() == hung_process) {
+          *result = render_frame_host->GetLastCommittedURL();
+          return content::RenderFrameHost::FrameIterationAction::kStop;
+        }
+        return content::RenderFrameHost::FrameIterationAction::kContinue;
+      },
+      hung_process, &result));
 
   // If a frame is attempting to commit a navigation into a hung renderer
   // process, then its |frame->GetProcess()| will still return the process
   // hosting the previously committed navigation.  In such case, the loop above
   // might not find any matching frame.
-  return GURL();
+  return result;
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.cc b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.cc
index e2d680f..0fcc66f 100644
--- a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.cc
+++ b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.cc
@@ -31,8 +31,7 @@
   if (new_entries.empty())
     return;
 
-  Browser* browser = chrome::FindBrowserWithProfile(profile_);
-  if (platform_util::IsWindowActive(browser->window()->GetNativeWindow())) {
+  if (GetActiveDelegate()) {
     ShowToolbarButton(*new_entries.at(0));
     return;
   }
@@ -73,6 +72,8 @@
 
 void SendTabToSelfToolbarIconController::OnBrowserSetLastActive(
     Browser* browser) {
+  if (!GetActiveDelegate())
+    return;
   BrowserList::RemoveObserver(this);
 
   // Reset |entry_| because it's used to determine if the BrowserListObserver is
@@ -81,22 +82,46 @@
 
   if (!profile_ || !entry)
     return;
-  if (browser == chrome::FindBrowserWithProfile(profile_))
+  if (browser == chrome::FindBrowserWithProfile(profile_)) {
     ShowToolbarButton(*entry);
+    entry_ = nullptr;
+  }
 }
 
 void SendTabToSelfToolbarIconController::ShowToolbarButton(
     const SendTabToSelfEntry& entry) {
-  if (!delegate_)
+  auto* active_delegate = GetActiveDelegate();
+  if (!active_delegate) {
     return;
+  }
 
   send_tab_to_self::RecordNotificationShown();
-  delegate_->Show(entry);
+  active_delegate->Show(entry);
 }
 
-void SendTabToSelfToolbarIconController::SetDelegate(
+void SendTabToSelfToolbarIconController::AddDelegate(
     SendTabToSelfToolbarIconControllerDelegate* delegate) {
-  delegate_ = delegate;
+  delegate_list_.push_back(delegate);
+}
+
+void SendTabToSelfToolbarIconController::RemoveDelegate(
+    SendTabToSelfToolbarIconControllerDelegate* delegate) {
+  for (unsigned int i = 0; i < delegate_list_.size(); i++) {
+    if (delegate_list_[i] == delegate) {
+      delegate_list_.erase(delegate_list_.begin() + i);
+      return;
+    }
+  }
+}
+
+SendTabToSelfToolbarIconControllerDelegate*
+SendTabToSelfToolbarIconController::GetActiveDelegate() {
+  for (auto* delegate : delegate_list_) {
+    if (delegate->IsActive()) {
+      return delegate;
+    }
+  }
+  return nullptr;
 }
 
 void SendTabToSelfToolbarIconController::LogNotificationOpened() {
diff --git a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.h b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.h
index 856ccd71..00ab878e 100644
--- a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.h
+++ b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller.h
@@ -40,7 +40,9 @@
 
   void ShowToolbarButton(const SendTabToSelfEntry& entry);
 
-  void SetDelegate(SendTabToSelfToolbarIconControllerDelegate* delegate);
+  void AddDelegate(SendTabToSelfToolbarIconControllerDelegate* delegate);
+
+  void RemoveDelegate(SendTabToSelfToolbarIconControllerDelegate* delegate);
 
   Profile* profile() const { return profile_; }
 
@@ -53,7 +55,9 @@
 
   std::unique_ptr<SendTabToSelfEntry> entry_;
 
-  SendTabToSelfToolbarIconControllerDelegate* delegate_;
+  std::vector<SendTabToSelfToolbarIconControllerDelegate*> delegate_list_;
+
+  SendTabToSelfToolbarIconControllerDelegate* GetActiveDelegate();
 };
 
 }  // namespace send_tab_to_self
diff --git a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller_delegate.h b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller_delegate.h
index 72c8169..2d455a82 100644
--- a/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller_delegate.h
+++ b/chrome/browser/ui/send_tab_to_self/send_tab_to_self_toolbar_icon_controller_delegate.h
@@ -15,6 +15,8 @@
  public:
   virtual void Show(const SendTabToSelfEntry& entry) = 0;
 
+  virtual bool IsActive() = 0;
+
  protected:
   virtual ~SendTabToSelfToolbarIconControllerDelegate() = default;
 };
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
index d2c40a0..885ff33 100644
--- a/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_bubble_controller.cc
@@ -167,7 +167,7 @@
 
   SharingHubModel* model = GetSharingHubModel();
   if (model)
-    model->GetThirdPartyActionList(web_contents_, &actions);
+    model->GetThirdPartyActionList(&actions);
 
   return actions;
 }
diff --git a/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc b/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc
index 0c627c8..75c63198 100644
--- a/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc
+++ b/chrome/browser/ui/sharing_hub/sharing_hub_sub_menu_model.cc
@@ -71,7 +71,7 @@
   std::vector<SharingHubAction> first_party_actions;
   std::vector<SharingHubAction> third_party_actions;
   model->GetFirstPartyActionList(web_contents, &first_party_actions);
-  model->GetThirdPartyActionList(web_contents, &third_party_actions);
+  model->GetThirdPartyActionList(&third_party_actions);
 
   for (auto action : first_party_actions) {
     AddItem(action.command_id, action.title);
diff --git a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
index ccd2df2..3dbbdfb 100644
--- a/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
+++ b/chrome/browser/ui/side_search/side_search_side_contents_helper.cc
@@ -4,9 +4,143 @@
 
 #include "chrome/browser/ui/side_search/side_search_side_contents_helper.h"
 
+#include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h"
+#include "components/google/core/common/google_util.h"
+#include "content/public/browser/navigation_handle.h"
+#include "content/public/browser/navigation_throttle.h"
+#include "content/public/browser/page_navigator.h"
+#include "net/base/url_util.h"
+#include "third_party/blink/public/common/user_agent/user_agent_metadata.h"
+#include "url/gurl.h"
+
+namespace {
+
+constexpr char kSideSearchQueryParam[] = "sidesearch";
+constexpr char kSideSearchVersion[] = "1";
+
+#if !defined(OS_CHROMEOS)
+constexpr char kChromeOSUserAgent[] =
+    "Mozilla/5.0 (X11; CrOS x86_64 14233.0.0) AppleWebKit/537.36 (KHTML, like "
+    "Gecko) Chrome/96.0.4650.0 Safari/537.36";
+#endif  // !defined(OS_CHROMEOS)
+
+class SideSearchContentsThrottle : public content::NavigationThrottle {
+ public:
+  explicit SideSearchContentsThrottle(
+      content::NavigationHandle* navigation_handle)
+      : NavigationThrottle(navigation_handle) {}
+
+  // NavigationThrottle overrides.
+  ThrottleCheckResult WillStartRequest() override {
+    return HandleSidePanelRequest();
+  }
+  ThrottleCheckResult WillRedirectRequest() override {
+    return HandleSidePanelRequest();
+  }
+  const char* GetNameForLogging() override {
+    return "SideSearchContentsThrottle";
+  }
+
+ private:
+  ThrottleCheckResult HandleSidePanelRequest() {
+    const auto& url = navigation_handle()->GetURL();
+
+    // Allow Google search navigations to proceed in the side panel.
+    if (google_util::IsGoogleSearchUrl(url))
+      return NavigationThrottle::PROCEED;
+
+    // Route all non-Google search URLs to the tab contents associated with this
+    // side contents. This throttle will only be applied to WebContents objects
+    // that are hosted in the side panel. Hence all intercepted navigations will
+    // have a SideSearchContentsHelper.
+    auto* side_contents_helper = SideSearchSideContentsHelper::FromWebContents(
+        navigation_handle()->GetWebContents());
+    DCHECK(side_contents_helper);
+    content::OpenURLParams params =
+        content::OpenURLParams::FromNavigationHandle(navigation_handle());
+    // TODO(tluk): Remove this when landing on trunk (fix landing at
+    // https://crrev.com/c/3171921).
+    params.redirect_chain.pop_back();
+    side_contents_helper->NavigateInTabContents(params);
+    return content::NavigationThrottle::CANCEL;
+  }
+};
+
+}  // namespace
+
 SideSearchSideContentsHelper::~SideSearchSideContentsHelper() = default;
 
+std::unique_ptr<content::NavigationThrottle>
+SideSearchSideContentsHelper::MaybeCreateThrottleFor(
+    content::NavigationHandle* handle) {
+  // Only add a SideSearchContentsThrottle for side contentses.
+  auto* helper =
+      SideSearchSideContentsHelper::FromWebContents(handle->GetWebContents());
+  if (!helper)
+    return nullptr;
+  return std::make_unique<SideSearchContentsThrottle>(handle);
+}
+
+void SideSearchSideContentsHelper::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  // DidFinishNavigation triggers even if the navigation has been cancelled by
+  // the throttle. Early return if this is the case.
+  if (!navigation_handle->IsInPrimaryMainFrame() ||
+      navigation_handle->IsSameDocument() ||
+      !navigation_handle->HasCommitted()) {
+    return;
+  }
+
+  const auto& url = navigation_handle->GetURL();
+  DCHECK(google_util::IsGoogleSearchUrl(url));
+  DCHECK(delegate_);
+  delegate_->LastSearchURLUpdated(url);
+}
+
+void SideSearchSideContentsHelper::NavigateInTabContents(
+    const content::OpenURLParams& params) {
+  DCHECK(delegate_);
+  delegate_->NavigateInTabContents(params);
+}
+
+void SideSearchSideContentsHelper::LoadURL(const GURL& url) {
+  DCHECK(google_util::IsGoogleSearchUrl(url));
+
+  // Do not reload the side contents if already navigated to `url`.
+  if (web_contents()->GetLastCommittedURL() == url)
+    return;
+
+  GURL side_search_url =
+      net::AppendQueryParameter(url, kSideSearchQueryParam, kSideSearchVersion);
+  content::NavigationController::LoadURLParams load_url_params(side_search_url);
+
+  // Fake the user agent on non ChromeOS systems to allow for development and
+  // testing. This is needed as the side search SRP is only served to ChromeOS
+  // user agents.
+#if !defined(OS_CHROMEOS)
+  load_url_params.transition_type = ui::PAGE_TRANSITION_AUTO_TOPLEVEL;
+  load_url_params.override_user_agent =
+      content::NavigationController::UA_OVERRIDE_TRUE;
+#endif  // defined(OS_CHROMEOS)
+
+  web_contents()->GetController().LoadURLWithParams(load_url_params);
+}
+
+void SideSearchSideContentsHelper::SetDelegate(Delegate* delegate) {
+  DCHECK(!delegate_);
+  delegate_ = delegate;
+}
+
 SideSearchSideContentsHelper::SideSearchSideContentsHelper(
-    content::WebContents* web_contents) {}
+    content::WebContents* web_contents) {
+  Observe(web_contents);
+
+#if !defined(OS_CHROMEOS)
+  web_contents->SetUserAgentOverride(
+      blink::UserAgentOverride::UserAgentOnly(kChromeOSUserAgent), true);
+  web_contents->SetRendererInitiatedUserAgentOverrideOption(
+      content::NavigationController::UA_OVERRIDE_TRUE);
+#endif  // !defined(OS_CHROMEOS)
+}
 
 WEB_CONTENTS_USER_DATA_KEY_IMPL(SideSearchSideContentsHelper)
diff --git a/chrome/browser/ui/side_search/side_search_side_contents_helper.h b/chrome/browser/ui/side_search/side_search_side_contents_helper.h
index 7a95bb7..d4dec40c 100644
--- a/chrome/browser/ui/side_search/side_search_side_contents_helper.h
+++ b/chrome/browser/ui/side_search/side_search_side_contents_helper.h
@@ -5,22 +5,63 @@
 #ifndef CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_SIDE_CONTENTS_HELPER_H_
 #define CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_SIDE_CONTENTS_HELPER_H_
 
+#include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
 namespace content {
+class NavigationHandle;
+class NavigationThrottle;
 class WebContents;
 }  // namespace content
 
+class GURL;
+
 // Side Search helper for the WebContents hosted in the side panel.
 class SideSearchSideContentsHelper
-    : public content::WebContentsUserData<SideSearchSideContentsHelper> {
+    : public content::WebContentsObserver,
+      public content::WebContentsUserData<SideSearchSideContentsHelper> {
  public:
+  class Delegate {
+   public:
+    // Called by the side contents helper to navigate its associated tab
+    // contents.
+    virtual void NavigateInTabContents(
+        const content::OpenURLParams& params) = 0;
+
+    // Called when the last search URL encountered by the side panel has been
+    // updated.
+    virtual void LastSearchURLUpdated(const GURL& url) = 0;
+  };
+
   ~SideSearchSideContentsHelper() override;
 
+  // Maybe installs a throttle for the given navigation.
+  static std::unique_ptr<content::NavigationThrottle> MaybeCreateThrottleFor(
+      content::NavigationHandle* handle);
+
+  // content::WebContentsObserver:
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
+
+  // Navigates the associated tab contents to `url`.
+  void NavigateInTabContents(const content::OpenURLParams& params);
+
+  // Loads the `url` in the side contents, applying any additional headers as
+  // necessary.
+  void LoadURL(const GURL& url);
+
+  // Called to set the tab contents associated with this side panel contents.
+  // The tab contents will always outlive this helper and its associated side
+  // contents.
+  void SetDelegate(Delegate* delegate);
+
  private:
   friend class content::WebContentsUserData<SideSearchSideContentsHelper>;
   explicit SideSearchSideContentsHelper(content::WebContents* web_contents);
 
+  // `delegate_` will outlive the SideContentsWrapper.
+  Delegate* delegate_ = nullptr;
+
   WEB_CONTENTS_USER_DATA_KEY_DECL();
 };
 
diff --git a/chrome/browser/ui/side_search/side_search_side_contents_helper_unittest.cc b/chrome/browser/ui/side_search/side_search_side_contents_helper_unittest.cc
new file mode 100644
index 0000000..36d3da3
--- /dev/null
+++ b/chrome/browser/ui/side_search/side_search_side_contents_helper_unittest.cc
@@ -0,0 +1,136 @@
+// Copyright 2021 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/ui/side_search/side_search_side_contents_helper.h"
+
+#include <memory>
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ui/ui_features.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_renderer_host.h"
+#include "content/public/test/web_contents_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace {
+
+constexpr char kGoogleSearchURL[] = "https://www.google.com/search?q=test1";
+constexpr char kGoogleSearchHomePageURL[] = "https://www.google.com";
+constexpr char kNonGoogleURL[] = "https://www.test.com";
+
+class MockSideContentsDelegate : public SideSearchSideContentsHelper::Delegate {
+ public:
+  MockSideContentsDelegate() = default;
+  MockSideContentsDelegate(const MockSideContentsDelegate&) = delete;
+  MockSideContentsDelegate& operator=(const MockSideContentsDelegate&) = delete;
+  ~MockSideContentsDelegate() = default;
+
+  // SideSearchSideContentsHelper::Delegate:
+  void NavigateInTabContents(const content::OpenURLParams& params) override {
+    tab_contents_url_ = params.url;
+    ++navigate_in_tab_contents_times_called_;
+  }
+  void LastSearchURLUpdated(const GURL& url) override {
+    last_search_url_ = url;
+  }
+
+  const GURL& tab_contents_url() const { return tab_contents_url_; }
+
+  const GURL& last_search_url() const { return last_search_url_; }
+
+  int navigate_in_tab_contents_times_called() const {
+    return navigate_in_tab_contents_times_called_;
+  }
+
+ private:
+  GURL tab_contents_url_;
+  GURL last_search_url_;
+  int navigate_in_tab_contents_times_called_ = 0;
+};
+
+}  // namespace
+
+namespace test {
+
+class SideSearchSideContentsHelperTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(features::kSideSearch);
+    side_contents_ =
+        content::WebContentsTester::CreateTestWebContents(&profile_, nullptr);
+    SideSearchSideContentsHelper::CreateForWebContents(side_contents());
+    helper()->SetDelegate(&delegate_);
+    Test::SetUp();
+  }
+
+ protected:
+  void LoadURL(const char* url) {
+    const int initial_tab_navigation_count =
+        delegate_.navigate_in_tab_contents_times_called();
+    side_contents()->GetController().LoadURL(GURL(url), content::Referrer(),
+                                             ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
+                                             std::string());
+    const int final_tab_navigation_count =
+        delegate_.navigate_in_tab_contents_times_called();
+
+    // If NavigateInTabContents() has been called this indicates that the side
+    // contents' navigation has been cancelled by the throttle. Avoid committing
+    // the side contents' navigation in this case as it will trigger a DCHECK().
+    if (side_contents()->GetController().GetPendingEntry() &&
+        initial_tab_navigation_count == final_tab_navigation_count) {
+      content::WebContentsTester::For(side_contents())
+          ->CommitPendingNavigation();
+    }
+  }
+
+  content::NavigationEntry* GetLastCommittedSideContentsEntry() {
+    return side_contents()->GetController().GetLastCommittedEntry();
+  }
+
+  const MockSideContentsDelegate& delegate() { return delegate_; }
+
+  content::WebContents* side_contents() { return side_contents_.get(); }
+
+  SideSearchSideContentsHelper* helper() {
+    return SideSearchSideContentsHelper::FromWebContents(side_contents());
+  }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+  content::RenderViewHostTestEnabler rvh_enabler_;
+  TestingProfile profile_;
+  std::unique_ptr<content::WebContents> side_contents_;
+  MockSideContentsDelegate delegate_;
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(SideSearchSideContentsHelperTest, GoogleSearchURLsNavigateSideContents) {
+  LoadURL(kGoogleSearchURL);
+  EXPECT_EQ(GURL(kGoogleSearchURL),
+            GetLastCommittedSideContentsEntry()->GetURL());
+  EXPECT_EQ(GURL(kGoogleSearchURL), delegate().last_search_url());
+  EXPECT_TRUE(delegate().tab_contents_url().is_empty());
+}
+
+TEST_F(SideSearchSideContentsHelperTest,
+       NonGoogleSearchURLNavigatesTabContents) {
+  LoadURL(kNonGoogleURL);
+  EXPECT_EQ(nullptr, GetLastCommittedSideContentsEntry());
+  EXPECT_TRUE(delegate().last_search_url().is_empty());
+  EXPECT_EQ(GURL(kNonGoogleURL), delegate().tab_contents_url());
+}
+
+TEST_F(SideSearchSideContentsHelperTest,
+       GoogleHomePageURLNavigatesTabContents) {
+  LoadURL(kGoogleSearchHomePageURL);
+  EXPECT_EQ(nullptr, GetLastCommittedSideContentsEntry());
+  EXPECT_TRUE(delegate().last_search_url().is_empty());
+  EXPECT_EQ(GURL(kGoogleSearchHomePageURL), delegate().tab_contents_url());
+}
+
+}  // namespace test
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
index 64ab943..611365a 100644
--- a/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
+++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper.cc
@@ -5,20 +5,43 @@
 #include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h"
 
 #include "chrome/browser/ui/side_search/side_search_side_contents_helper.h"
+#include "chrome/common/webui_url_constants.h"
 #include "components/google/core/common/google_util.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/navigation_controller.h"
 #include "content/public/browser/navigation_handle.h"
 
 SideSearchTabContentsHelper::~SideSearchTabContentsHelper() = default;
 
+void SideSearchTabContentsHelper::NavigateInTabContents(
+    const content::OpenURLParams& params) {
+  web_contents()->GetController().LoadURLWithParams(
+      content::NavigationController::LoadURLParams(params));
+}
+
+void SideSearchTabContentsHelper::LastSearchURLUpdated(const GURL& url) {
+  DCHECK(google_util::IsGoogleSearchUrl(url));
+  last_search_url_ = url;
+}
+
 void SideSearchTabContentsHelper::DidFinishNavigation(
     content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInPrimaryMainFrame() ||
+      navigation_handle->IsSameDocument() ||
+      !navigation_handle->HasCommitted()) {
+    return;
+  }
+
   const auto& url = navigation_handle->GetURL();
 
-  if (!google_util::IsGoogleSearchUrl(url))
-    return;
+  if (google_util::IsGoogleSearchUrl(url)) {
+    // Capture the URL here in case the side contents is closed before the
+    // navigation completes.
+    last_search_url_ = url;
 
-  last_search_url_ = url;
+    if (side_panel_contents_)
+      UpdateSideContentsNavigation();
+  }
 }
 
 content::WebContents* SideSearchTabContentsHelper::GetSidePanelContents() {
@@ -26,9 +49,31 @@
     CreateSidePanelContents();
 
   DCHECK(side_panel_contents_);
+  UpdateSideContentsNavigation();
   return side_panel_contents_.get();
 }
 
+void SideSearchTabContentsHelper::ClearSidePanelContents() {
+  // It is safe to reset this here as any views::WebViews hosting this
+  // WebContents will clear their reference to this away during its destruction.
+  side_panel_contents_.reset();
+}
+
+bool SideSearchTabContentsHelper::CanShowSidePanelForCommittedNavigation() {
+  const GURL& url = web_contents()->GetLastCommittedURL();
+  return last_search_url_ && !google_util::IsGoogleSearchUrl(url) &&
+         !google_util::IsGoogleHomePageUrl(url) &&
+         url.spec() != chrome::kChromeUINewTabURL;
+}
+
+void SideSearchTabContentsHelper::SetSidePanelContentsForTesting(
+    std::unique_ptr<content::WebContents> side_panel_contents) {
+  side_panel_contents_ = std::move(side_panel_contents);
+  SideSearchSideContentsHelper::CreateForWebContents(
+      side_panel_contents_.get());
+  GetSideContentsHelper()->SetDelegate(this);
+}
+
 SideSearchTabContentsHelper::SideSearchTabContentsHelper(
     content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents) {}
@@ -47,6 +92,15 @@
           web_contents()->GetBrowserContext(), nullptr));
   SideSearchSideContentsHelper::CreateForWebContents(
       side_panel_contents_.get());
+  GetSideContentsHelper()->SetDelegate(this);
+}
+
+void SideSearchTabContentsHelper::UpdateSideContentsNavigation() {
+  DCHECK(side_panel_contents_);
+  // Only update the side panel contents with the latest `last_search_url_` if
+  // present
+  if (last_search_url_)
+    GetSideContentsHelper()->LoadURL(last_search_url_.value());
 }
 
 WEB_CONTENTS_USER_DATA_KEY_IMPL(SideSearchTabContentsHelper)
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper.h b/chrome/browser/ui/side_search/side_search_tab_contents_helper.h
index 9bda151f..21a1ba8a 100644
--- a/chrome/browser/ui/side_search/side_search_tab_contents_helper.h
+++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_TAB_CONTENTS_HELPER_H_
 #define CHROME_BROWSER_UI_SIDE_SEARCH_SIDE_SEARCH_TAB_CONTENTS_HELPER_H_
 
+#include "chrome/browser/ui/side_search/side_search_side_contents_helper.h"
 #include "content/public/browser/web_contents_observer.h"
 #include "content/public/browser/web_contents_user_data.h"
 
@@ -14,15 +15,19 @@
 }  // namespace content
 
 class GURL;
-class SideSearchSideContentsHelper;
 
 // Side Search helper for the WebContents hosted in the browser's main tab area.
 class SideSearchTabContentsHelper
-    : public content::WebContentsObserver,
+    : public SideSearchSideContentsHelper::Delegate,
+      public content::WebContentsObserver,
       public content::WebContentsUserData<SideSearchTabContentsHelper> {
  public:
   ~SideSearchTabContentsHelper() override;
 
+  // SideContentsWrapper::Delegate:
+  void NavigateInTabContents(const content::OpenURLParams& params) override;
+  void LastSearchURLUpdated(const GURL& url) override;
+
   // content::WebContentsObserver:
   void DidFinishNavigation(
       content::NavigationHandle* navigation_handle) override;
@@ -31,6 +36,29 @@
   // currently exist.
   content::WebContents* GetSidePanelContents();
 
+  // Called by clients as a hint to the tab helper to clear away its
+  // `side_panel_contents_` if it exists. Caching strategies can leverage this
+  // hint and reset the `side_panel_contents_` at some later point in time.
+  void ClearSidePanelContents();
+
+  // Returns true if the side panel can be shown for the currently committed
+  // navigation entry.
+  bool CanShowSidePanelForCommittedNavigation();
+
+  bool toggled_open() const { return toggled_open_; }
+  void set_toggled_open(bool toggled_open) { toggled_open_ = toggled_open; }
+
+  void SetSidePanelContentsForTesting(
+      std::unique_ptr<content::WebContents> side_panel_contents);
+
+  content::WebContents* side_panel_contents_for_testing() const {
+    return side_panel_contents_.get();
+  }
+
+  const absl::optional<GURL>& last_search_url_for_testing() {
+    return last_search_url_;
+  }
+
  private:
   friend class content::WebContentsUserData<SideSearchTabContentsHelper>;
   explicit SideSearchTabContentsHelper(content::WebContents* web_contents);
@@ -38,6 +66,10 @@
   // Gets the helper for the side contents.
   SideSearchSideContentsHelper* GetSideContentsHelper();
 
+  // Navigates `side_panel_contents_` to the tab's `last_search_url_` if needed.
+  // Should only be called when `side_contents_active_`.
+  void UpdateSideContentsNavigation();
+
   // Creates the `side_panel_contents_` associated with this helper's tab
   // contents.
   void CreateSidePanelContents();
@@ -45,6 +77,10 @@
   // The last Google search URL encountered by this tab contents.
   absl::optional<GURL> last_search_url_;
 
+  // A flag to track whether the current tab has its side panel toggled open.
+  // Only used with the kSideSearchStatePerTab flag.
+  bool toggled_open_ = false;
+
   // The side panel contents associated with this tab contents.
   // TODO(tluk): Update the way we manage the `side_panel_contents_` to avoid
   // keeping the object around when not needed by the feature.
diff --git a/chrome/browser/ui/side_search/side_search_tab_contents_helper_unittest.cc b/chrome/browser/ui/side_search/side_search_tab_contents_helper_unittest.cc
new file mode 100644
index 0000000..7249e9a
--- /dev/null
+++ b/chrome/browser/ui/side_search/side_search_tab_contents_helper_unittest.cc
@@ -0,0 +1,219 @@
+// Copyright 2021 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/ui/side_search/side_search_tab_contents_helper.h"
+
+#include <memory>
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ui/ui_features.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/navigation_entry.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_renderer_host.h"
+#include "content/public/test/web_contents_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace {
+
+constexpr char kGoogleSearchURL1[] = "https://www.google.com/search?q=test1";
+constexpr char kGoogleSearchURL2[] = "https://www.google.com/search?q=test2";
+constexpr char kGoogleSearchHomePageURL[] = "https://www.google.com";
+constexpr char kNonGoogleURL[] = "https://www.test.com";
+
+// Tests to see if `navigated_url` matches `stored_url`. We cannot directly
+// compare as the "sidesearch=1" query param may have been appended to the
+// `stored_url` to ensure Google serves the side search SRP to the chrome
+// client.
+bool DoesURLMatch(const char* navigated_url, const GURL& stored_url) {
+  return stored_url.spec().find(GURL(navigated_url).spec()) !=
+         std::string::npos;
+}
+
+bool DoesURLMatch(const char* navigated_url,
+                  const absl::optional<GURL>& stored_url) {
+  return stored_url && DoesURLMatch(navigated_url, stored_url.value());
+}
+
+}  // namespace
+
+namespace test {
+
+class SideSearchTabContentsHelperTest : public ::testing::Test {
+ public:
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(features::kSideSearch);
+    web_contents_ =
+        content::WebContentsTester::CreateTestWebContents(&profile_, nullptr);
+    SideSearchTabContentsHelper::CreateForWebContents(web_contents_.get());
+    helper()->SetSidePanelContentsForTesting(
+        content::WebContentsTester::CreateTestWebContents(&profile_, nullptr));
+    Test::SetUp();
+  }
+
+ protected:
+  void LoadURL(const char* url) {
+    web_contents()->GetController().LoadURL(GURL(url), content::Referrer(),
+                                            ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
+                                            std::string());
+    CommitPendingNavigation();
+  }
+
+  void GoBack() {
+    ASSERT_TRUE(web_contents()->GetController().CanGoBack());
+    web_contents()->GetController().GoBack();
+    CommitPendingNavigation();
+  }
+
+  void GoForward() {
+    ASSERT_TRUE(web_contents()->GetController().CanGoForward());
+    web_contents()->GetController().GoForward();
+    CommitPendingNavigation();
+  }
+
+  void CommitPendingNavigation() {
+    content::WebContentsTester::For(web_contents())->CommitPendingNavigation();
+
+    if (side_contents() && side_contents()->GetController().GetPendingEntry()) {
+      content::WebContentsTester::For(side_contents())
+          ->CommitPendingNavigation();
+    }
+  }
+
+  content::NavigationEntry* GetLastCommittedSideContentsEntry() {
+    DCHECK(side_contents());
+    return side_contents()->GetController().GetLastCommittedEntry();
+  }
+
+  content::WebContents* web_contents() { return web_contents_.get(); }
+
+  content::WebContents* side_contents() {
+    return helper()->GetSidePanelContents();
+  }
+
+  SideSearchTabContentsHelper* helper() {
+    return SideSearchTabContentsHelper::FromWebContents(web_contents_.get());
+  }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_;
+  content::RenderViewHostTestEnabler rvh_enabler_;
+  TestingProfile profile_;
+  std::unique_ptr<content::WebContents> web_contents_;
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+TEST_F(SideSearchTabContentsHelperTest, LastSearchURLUpdatesCorrectly) {
+  // When a tab is first opened there should be no last encountered Google SRP.
+  EXPECT_FALSE(helper()->last_search_url_for_testing().has_value());
+  EXPECT_EQ(nullptr, GetLastCommittedSideContentsEntry());
+
+  // Navigating to a Google SRP should update the `last_search_url`.
+  LoadURL(kGoogleSearchURL1);
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL1, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL1,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  // Navigating to a non-Google SRP URL should not change the `last_search_url`.
+  LoadURL(kNonGoogleURL);
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL1, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL1,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  // Navigating again to a Google SRP should update the `last_search_url`.
+  LoadURL(kGoogleSearchURL2);
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL2, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL2,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  // Going backwards to the non-Google SRP URL should not update the last search
+  // url.
+  GoBack();
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL2, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL2,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  // Going back to the original Google SRP should update the `last_search_url`
+  // to that Google SRP URL.
+  GoBack();
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL1, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL1,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  // Going forward to the non-Google URL shouldn't change the `last_search_url`.
+  GoForward();
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL1, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL1,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  // Going forward to the Google SRP URL should update the `last_search_url` to
+  // that Google SRP URL.
+  GoForward();
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL2, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL2,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+}
+
+TEST_F(SideSearchTabContentsHelperTest, LastSearchURLIgnoresGoogleHomePage) {
+  EXPECT_FALSE(helper()->last_search_url_for_testing().has_value());
+
+  LoadURL(kGoogleSearchURL1);
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL1, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL1,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  // Navigating to the Google home page should not update the `last_search_url`.
+  LoadURL(kGoogleSearchHomePageURL);
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL1, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL1,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+
+  LoadURL(kGoogleSearchURL2);
+  EXPECT_TRUE(
+      DoesURLMatch(kGoogleSearchURL2, helper()->last_search_url_for_testing()));
+  EXPECT_TRUE(DoesURLMatch(kGoogleSearchURL2,
+                           GetLastCommittedSideContentsEntry()->GetURL()));
+}
+
+TEST_F(SideSearchTabContentsHelperTest, IndicatesWhenSidePanelShouldBeShown) {
+  // With no initial navigation the side panel should not be showing.
+  EXPECT_FALSE(helper()->CanShowSidePanelForCommittedNavigation());
+
+  // If no previous Google SRP has been seen for this tab contents the side
+  // panel should not show.
+  LoadURL(kNonGoogleURL);
+  EXPECT_FALSE(helper()->CanShowSidePanelForCommittedNavigation());
+
+  // The side panel should not be visible on Google SRP pages.
+  LoadURL(kGoogleSearchURL1);
+  EXPECT_FALSE(helper()->CanShowSidePanelForCommittedNavigation());
+
+  // If a Google SRP has previously been navigated to it can appear in the side
+  // panel if on a non-Google page.
+  LoadURL(kNonGoogleURL);
+  EXPECT_TRUE(helper()->CanShowSidePanelForCommittedNavigation());
+
+  // The side panel should not appear when on the Google home page.
+  LoadURL(kGoogleSearchHomePageURL);
+  EXPECT_FALSE(helper()->CanShowSidePanelForCommittedNavigation());
+}
+
+TEST_F(SideSearchTabContentsHelperTest, ClearsSidePanelContentsWhenAsked) {
+  DCHECK_NE(nullptr, helper()->side_panel_contents_for_testing());
+  helper()->ClearSidePanelContents();
+  DCHECK_EQ(nullptr, helper()->side_panel_contents_for_testing());
+}
+
+}  // namespace test
diff --git a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
index 7d15be2..8175e55 100644
--- a/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
+++ b/chrome/browser/ui/views/autofill/autofill_popup_view_native_views.cc
@@ -170,6 +170,9 @@
   if (icon_str == "empty")
     return ImageViewFromVectorIcon(omnibox::kHttpIcon);
 
+  if (icon_str == "fingerprint")
+    return ImageViewFromVectorIcon(kFingerprintIcon);
+
   if (icon_str == "google") {
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
     return ImageViewFromImageSkia(gfx::CreateVectorIcon(
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc
index 2e9b6c89..51da49d 100644
--- a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc
@@ -11,7 +11,10 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_dialogs.h"
+#include "chrome/browser/ui/hats/hats_service.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
 #include "chrome/browser/ui/views/accessibility/theme_tracking_non_accessible_image_view.h"
 #include "chrome/browser/ui/views/autofill/payments/dialog_view_ids.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
@@ -62,6 +65,14 @@
                             base::Unretained(this))));
     InitFootnoteView(legal_message_view_);
   }
+
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+  HatsService* hats_service =
+      HatsServiceFactory::GetForProfile(profile, /*create_if_necessary=*/true);
+  CHECK(hats_service);
+  hats_service->LaunchDelayedSurveyForWebContents(
+      kHatsSurveyTriggerAutofillCard, web_contents, 10000);
 }
 
 void SaveCardOfferBubbleViews::Init() {
diff --git a/chrome/browser/ui/views/autofill/save_address_profile_view.cc b/chrome/browser/ui/views/autofill/save_address_profile_view.cc
index 5452bbe..e51e2de 100644
--- a/chrome/browser/ui/views/autofill/save_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/save_address_profile_view.cc
@@ -9,7 +9,10 @@
 #include "base/strings/string_util.h"
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/browser_process.h"
+#include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/autofill/save_update_address_profile_bubble_controller.h"
+#include "chrome/browser/ui/hats/hats_service.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
 #include "chrome/browser/ui/views/accessibility/theme_tracking_non_accessible_image_view.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/grit/theme_resources.h"
@@ -19,6 +22,7 @@
 #include "components/autofill/core/common/autofill_features.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/vector_icons/vector_icons.h"
+#include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/simple_combobox_model.h"
 #include "ui/color/color_id.h"
@@ -307,6 +311,14 @@
                       CreateAddressSectionIcon(vector_icons::kExtensionIcon),
                       CreateNicknameEditableCombobox());
   }
+
+  Profile* browser_profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+  HatsService* hats_service = HatsServiceFactory::GetForProfile(
+      browser_profile, /*create_if_necessary=*/true);
+  CHECK(hats_service);
+  hats_service->LaunchDelayedSurveyForWebContents(
+      kHatsSurveyTriggerAutofillAddress, web_contents, 10000);
 }
 
 SaveAddressProfileView::~SaveAddressProfileView() = default;
diff --git a/chrome/browser/ui/views/crostini/crostini_expired_container_warning_view.cc b/chrome/browser/ui/views/crostini/crostini_expired_container_warning_view.cc
new file mode 100644
index 0000000..cb574728
--- /dev/null
+++ b/chrome/browser/ui/views/crostini/crostini_expired_container_warning_view.cc
@@ -0,0 +1,108 @@
+// Copyright 2021 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/ui/views/crostini/crostini_expired_container_warning_view.h"
+
+#include "chrome/browser/ui/views/chrome_layout_provider.h"
+#include "chrome/browser/ui/webui/chromeos/crostini_upgrader/crostini_upgrader_dialog.h"
+#include "chrome/grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/layout_provider.h"
+
+namespace {
+
+CrostiniExpiredContainerWarningView* g_crostini_expired_container_warning_view =
+    nullptr;
+
+}  // namespace
+
+void CrostiniExpiredContainerWarningView::Show(
+    Profile* profile,
+    std::vector<base::OnceClosure> callbacks) {
+  if (g_crostini_expired_container_warning_view) {
+    for (auto&& callback : callbacks) {
+      g_crostini_expired_container_warning_view->callbacks_.push_back(
+          std::move(callback));
+    }
+  } else {
+    g_crostini_expired_container_warning_view =
+        new CrostiniExpiredContainerWarningView(profile, std::move(callbacks));
+    CreateDialogWidget(g_crostini_expired_container_warning_view, nullptr,
+                       nullptr);
+  }
+
+  // Always call Show to bring the dialog to the front of the screen.
+  g_crostini_expired_container_warning_view->GetWidget()->Show();
+}
+
+CrostiniExpiredContainerWarningView::CrostiniExpiredContainerWarningView(
+    Profile* profile,
+    std::vector<base::OnceClosure> callbacks)
+    : profile_(profile),
+      callbacks_(std::move(callbacks)),
+      weak_ptr_factory_(this) {
+  // Make the dialog modal to force the user to make a decision.
+  SetModalType(ui::MODAL_TYPE_SYSTEM);
+
+  SetTitle(IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_TITLE);
+  SetButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
+  SetButtonLabel(ui::DIALOG_BUTTON_CANCEL,
+                 l10n_util::GetStringUTF16(
+                     IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_CONTINUE_BUTTON));
+  SetButtonLabel(ui::DIALOG_BUTTON_OK,
+                 l10n_util::GetStringUTF16(
+                     IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_UPGRADE_BUTTON));
+  SetShowCloseButton(false);
+
+  // Show upgrade dialog on accept, and pass in the callback.
+  SetAcceptCallback(base::BindOnce(
+      [](base::WeakPtr<CrostiniExpiredContainerWarningView> weak_this) {
+        chromeos::CrostiniUpgraderDialog::Show(
+            weak_this->profile_,
+            base::BindOnce(
+                [](std::vector<base::OnceClosure> callbacks) {
+                  for (auto&& callback : callbacks) {
+                    std::move(callback).Run();
+                  }
+                },
+                std::move(weak_this->callbacks_)));
+      },
+      weak_ptr_factory_.GetWeakPtr()));
+
+  // On cancel, call the callback directly.
+  SetCancelCallback(base::BindOnce(
+      [](base::WeakPtr<CrostiniExpiredContainerWarningView> weak_this) {
+        for (auto&& callback : weak_this->callbacks_) {
+          std::move(callback).Run();
+        }
+      },
+      weak_ptr_factory_.GetWeakPtr()));
+
+  set_fixed_width(ChromeLayoutProvider::Get()->GetDistanceMetric(
+      DISTANCE_STANDALONE_BUBBLE_PREFERRED_WIDTH));
+
+  views::LayoutProvider* provider = views::LayoutProvider::Get();
+  SetLayoutManager(std::make_unique<views::BoxLayout>(
+      views::BoxLayout::Orientation::kVertical,
+      provider->GetInsetsMetric(views::InsetsMetric::INSETS_DIALOG),
+      provider->GetDistanceMetric(views::DISTANCE_RELATED_CONTROL_VERTICAL)));
+
+  const std::u16string message =
+      l10n_util::GetStringUTF16(IDS_CROSTINI_EXPIRED_CONTAINER_WARNING_BODY);
+  views::Label* message_label = new views::Label(message);
+  message_label->SetMultiLine(true);
+  message_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  AddChildView(message_label);
+}
+
+CrostiniExpiredContainerWarningView::~CrostiniExpiredContainerWarningView() {
+  g_crostini_expired_container_warning_view = nullptr;
+}
+
+BEGIN_METADATA(CrostiniExpiredContainerWarningView,
+               views::BubbleDialogDelegateView)
+END_METADATA
diff --git a/chrome/browser/ui/views/crostini/crostini_expired_container_warning_view.h b/chrome/browser/ui/views/crostini/crostini_expired_container_warning_view.h
new file mode 100644
index 0000000..a728ae8
--- /dev/null
+++ b/chrome/browser/ui/views/crostini/crostini_expired_container_warning_view.h
@@ -0,0 +1,37 @@
+// Copyright 2021 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_UI_VIEWS_CROSTINI_CROSTINI_EXPIRED_CONTAINER_WARNING_VIEW_H_
+#define CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_EXPIRED_CONTAINER_WARNING_VIEW_H_
+
+#include "chrome/browser/ash/crostini/crostini_simple_types.h"
+#include "chrome/browser/ash/crostini/crostini_util.h"
+#include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/views/bubble/bubble_dialog_delegate_view.h"
+
+namespace crostini {
+enum class CrostiniResult;
+}  // namespace crostini
+
+class Profile;
+
+class CrostiniExpiredContainerWarningView
+    : public views::BubbleDialogDelegateView {
+ public:
+  METADATA_HEADER(CrostiniExpiredContainerWarningView);
+
+  static void Show(Profile* profile, std::vector<base::OnceClosure> callbacks);
+
+ private:
+  CrostiniExpiredContainerWarningView(Profile* profile,
+                                      std::vector<base::OnceClosure> callbacks);
+  ~CrostiniExpiredContainerWarningView() override;
+
+  Profile* const profile_;  // Not owned.
+  std::vector<base::OnceClosure> callbacks_;
+
+  base::WeakPtrFactory<CrostiniExpiredContainerWarningView> weak_ptr_factory_;
+};
+
+#endif  // CHROME_BROWSER_UI_VIEWS_CROSTINI_CROSTINI_EXPIRED_CONTAINER_WARNING_VIEW_H_
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
index c763979..6e850aa 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.cc
@@ -157,14 +157,9 @@
 SkColor BrowserNonClientFrameView::GetFrameColor(
     BrowserFrameActiveState active_state) const {
   return GetFrameThemeProvider()->GetColor(
-      GetTabStripBackgroundColorId(active_state));
-}
-
-int BrowserNonClientFrameView::GetTabStripBackgroundColorId(
-    BrowserFrameActiveState active_state) const {
-  return ShouldPaintAsActive(active_state)
-             ? ThemeProperties::COLOR_FRAME_ACTIVE
-             : ThemeProperties::COLOR_FRAME_INACTIVE;
+      ShouldPaintAsActive(active_state)
+          ? ThemeProperties::COLOR_FRAME_ACTIVE
+          : ThemeProperties::COLOR_FRAME_INACTIVE);
 }
 
 void BrowserNonClientFrameView::UpdateFrameColor() {
diff --git a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
index 15f98bd..6e3732c 100644
--- a/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
+++ b/chrome/browser/ui/views/frame/browser_non_client_frame_view.h
@@ -105,12 +105,6 @@
   SkColor GetFrameColor(BrowserFrameActiveState active_state =
                             BrowserFrameActiveState::kUseCurrent) const;
 
-  // Returns the background color id for the tab strip, for use with a
-  // `ThemeProvider`.
-  int GetTabStripBackgroundColorId(
-      BrowserFrameActiveState active =
-          BrowserFrameActiveState::kUseCurrent) const;
-
   // Called by BrowserView to signal the frame color has changed and needs
   // to be repainted.
   virtual void UpdateFrameColor();
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 6b2c45fe0..eec803de 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -658,7 +658,7 @@
   devtools_web_view->SetVisible(false);
 
   auto contents_web_view =
-      std::make_unique<ContentsWebView>(browser_->profile(), this);
+      std::make_unique<ContentsWebView>(browser_->profile());
   contents_web_view->SetID(VIEW_ID_TAB_CONTAINER);
 
   auto contents_container = std::make_unique<views::View>();
@@ -1278,6 +1278,18 @@
   if (app_banner_manager)
     ObserveAppBannerManager(app_banner_manager);
 
+#if BUILDFLAG(ENABLE_SIDE_SEARCH)
+  // Update the side panel before performing a layout on the BrowserView so that
+  // the layout takes into account the presence (or absence) of the side panel.
+  // This avoids unnecessary resize events propagating to the WebContents if it
+  // was added first and the layout was adjusted to accommodate the side panel
+  // later on.
+  if (side_search_controller_) {
+    side_search_controller_->UpdateSidePanelForContents(new_contents,
+                                                        old_contents);
+  }
+#endif  // BUILDFLAG(ENABLE_SIDE_SEARCH)
+
   UpdateUIForContents(new_contents);
   RevealTabStripIfNeeded();
 
@@ -1846,12 +1858,6 @@
   }
 }
 
-void BrowserView::PaintAsActiveChanged() {
-  if (contents_web_view_) {
-    contents_web_view_->PaintAsActiveChanged();
-  }
-}
-
 void BrowserView::DestroyBrowser() {
   // After this returns other parts of Chrome are going to be shutdown. Close
   // the window now so that we are deleted immediately and aren't left holding
@@ -3147,10 +3153,6 @@
           base::BindOnce(&BrowserView::OnFeatureEngagementTrackerInitialized,
                          weak_ptr_factory_.GetWeakPtr()));
 
-  paint_as_active_subscription_ =
-      GetWidget()->RegisterPaintAsActiveChangedCallback(base::BindRepeating(
-          &BrowserView::PaintAsActiveChanged, base::Unretained(this)));
-
   initialized_ = true;
 }
 
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h
index 2d875d7..b087e28a 100644
--- a/chrome/browser/ui/views/frame/browser_view.h
+++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -850,9 +850,6 @@
   // whenever the touch mode changes.
   void MaybeShowReadingListInSidePanelIPH();
 
-  // Called when the widget's paint-as-active status changes.
-  void PaintAsActiveChanged();
-
   // The BrowserFrame that hosts this view.
   BrowserFrame* frame_ = nullptr;
 
@@ -1070,8 +1067,6 @@
   absl::optional<ui::ThroughputTracker> loading_animation_tracker_;
 #endif
 
-  base::CallbackListSubscription paint_as_active_subscription_;
-
   mutable base::WeakPtrFactory<BrowserView> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/ui/views/frame/contents_web_view.cc b/chrome/browser/ui/views/frame/contents_web_view.cc
index 68392d14..7f88c3f0 100644
--- a/chrome/browser/ui/views/frame/contents_web_view.cc
+++ b/chrome/browser/ui/views/frame/contents_web_view.cc
@@ -5,14 +5,11 @@
 #include "chrome/browser/ui/views/frame/contents_web_view.h"
 
 #include "chrome/browser/themes/theme_properties.h"
-#include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/status_bubble_views.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/base/theme_provider.h"
-#include "ui/color/color_provider_utils.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_tree_owner.h"
 #include "ui/views/background.h"
@@ -22,11 +19,10 @@
 #include "ui/wm/core/window_util.h"
 #endif
 
-ContentsWebView::ContentsWebView(content::BrowserContext* browser_context,
-                                 const BrowserView* browser_view)
+ContentsWebView::ContentsWebView(content::BrowserContext* browser_context)
     : views::WebView(browser_context),
-      status_bubble_(nullptr),
-      browser_view_(browser_view) {}
+      status_bubble_(nullptr) {
+}
 
 ContentsWebView::~ContentsWebView() {
 }
@@ -68,21 +64,13 @@
   UpdateBackgroundColor();
 }
 
-void ContentsWebView::PaintAsActiveChanged() {
-  UpdateBackgroundColor();
-}
-
 void ContentsWebView::UpdateBackgroundColor() {
   const ui::ThemeProvider* const theme = GetThemeProvider();
   if (!theme)
     return;
 
-  const SkColor background = color_utils::GetResultingPaintColor(
-      theme->GetColor(web_contents() ? browser_view_->frame()
-                                           ->GetFrameView()
-                                           ->GetTabStripBackgroundColorId()
-                                     : ThemeProperties::COLOR_NTP_BACKGROUND),
-      SK_ColorWHITE);
+  const SkColor ntp_background = color_utils::GetResultingPaintColor(
+      theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND), SK_ColorWHITE);
   if (is_letterboxing()) {
     // Set the background color to a dark tint of the new tab page's background
     // color.  This is the color filled within the WebView's bounds when its
@@ -90,14 +78,14 @@
     // header file comments for more details.
     const int kBackgroundBrightness = 0x33;  // 20%
     // Make sure the background is opaque.
-    const SkColor dimmed_background =
-        SkColorSetARGB(SkColorGetA(background),
-                       SkColorGetR(background) * kBackgroundBrightness / 0xFF,
-                       SkColorGetG(background) * kBackgroundBrightness / 0xFF,
-                       SkColorGetB(background) * kBackgroundBrightness / 0xFF);
-    SetBackground(views::CreateSolidBackground(dimmed_background));
+    const SkColor dimmed_ntp_background = SkColorSetARGB(
+        SkColorGetA(ntp_background),
+        SkColorGetR(ntp_background) * kBackgroundBrightness / 0xFF,
+        SkColorGetG(ntp_background) * kBackgroundBrightness / 0xFF,
+        SkColorGetB(ntp_background) * kBackgroundBrightness / 0xFF);
+    SetBackground(views::CreateSolidBackground(dimmed_ntp_background));
   } else {
-    SetBackground(views::CreateSolidBackground(background));
+    SetBackground(views::CreateSolidBackground(ntp_background));
   }
   // Changing a view's background does not necessarily schedule the view to be
   // redrawn.
@@ -107,7 +95,7 @@
     content::RenderWidgetHostView* rwhv =
         web_contents()->GetRenderWidgetHostView();
     if (rwhv)
-      rwhv->SetBackgroundColor(background);
+      rwhv->SetBackgroundColor(ntp_background);
   }
 }
 
diff --git a/chrome/browser/ui/views/frame/contents_web_view.h b/chrome/browser/ui/views/frame/contents_web_view.h
index f344b781..a81ac41 100644
--- a/chrome/browser/ui/views/frame/contents_web_view.h
+++ b/chrome/browser/ui/views/frame/contents_web_view.h
@@ -13,7 +13,6 @@
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/controls/webview/webview.h"
 
-class BrowserView;
 class StatusBubbleViews;
 
 namespace ui {
@@ -26,8 +25,7 @@
       public WebContentsCloseHandlerDelegate {
  public:
   METADATA_HEADER(ContentsWebView);
-  ContentsWebView(content::BrowserContext* browser_context,
-                  const BrowserView* browser_view);
+  explicit ContentsWebView(content::BrowserContext* browser_context);
   ContentsWebView(const ContentsWebView&) = delete;
   ContentsWebView& operator=(const ContentsWebView&) = delete;
   ~ContentsWebView() override;
@@ -53,13 +51,9 @@
   void CloneWebContentsLayer() override;
   void DestroyClonedLayer() override;
 
-  // Called from BrowserView when its widget's paint-as-active status changes.
-  void PaintAsActiveChanged();
-
  private:
   void UpdateBackgroundColor();
   StatusBubbleViews* status_bubble_;
-  const BrowserView* const browser_view_;
 
   std::unique_ptr<ui::LayerTreeOwner> cloned_layer_tree_;
 };
diff --git a/chrome/browser/ui/views/overlay/overlay_window_views.cc b/chrome/browser/ui/views/overlay/overlay_window_views.cc
index aa2d336..93eb1f4 100644
--- a/chrome/browser/ui/views/overlay/overlay_window_views.cc
+++ b/chrome/browser/ui/views/overlay/overlay_window_views.cc
@@ -1064,11 +1064,11 @@
     UpdateControlsVisibility(true);
   }
 
-  // If there is no focus affordance on the buttons, only handle space key to
-  // for TogglePlayPause().
+  // If there is no focus affordance on the buttons and play/pause button is
+  // visible, only handle space key for TogglePlayPause().
   views::View* focused_view = GetFocusManager()->GetFocusedView();
   if (!focused_view && event->type() == ui::ET_KEY_PRESSED &&
-      event->key_code() == ui::VKEY_SPACE) {
+      event->key_code() == ui::VKEY_SPACE && show_play_pause_button_) {
     TogglePlayPause();
     event->SetHandled();
   }
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.cc b/chrome/browser/ui/views/passwords/password_save_update_view.cc
index 6de6f16b..0a85589a 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_view.cc
+++ b/chrome/browser/ui/views/passwords/password_save_update_view.cc
@@ -17,6 +17,8 @@
 #include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/feature_engagement/tracker_factory.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/hats/hats_service.h"
+#include "chrome/browser/ui/hats/hats_service_factory.h"
 #include "chrome/browser/ui/passwords/manage_passwords_view_utils.h"
 #include "chrome/browser/ui/passwords/password_dialog_prompts.h"
 #include "chrome/browser/ui/passwords/passwords_model_delegate.h"
@@ -33,6 +35,7 @@
 #include "components/feature_engagement/public/tracker.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "content/public/browser/storage_partition.h"
+#include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/combobox_model.h"
 #include "ui/base/models/combobox_model_observer.h"
@@ -452,6 +455,14 @@
   SetShowIcon(false);
 
   UpdateBubbleUIElements();
+
+  Profile* profile =
+      Profile::FromBrowserContext(web_contents->GetBrowserContext());
+  HatsService* hats_service =
+      HatsServiceFactory::GetForProfile(profile, /*create_if_necessary=*/true);
+  CHECK(hats_service);
+  hats_service->LaunchDelayedSurveyForWebContents(
+      kHatsSurveyTriggerAutofillPassword, web_contents, 10000);
 }
 
 PasswordSaveUpdateView::~PasswordSaveUpdateView() {
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.cc b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.cc
index f9a6c02e..dc25e3d 100644
--- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.cc
+++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.cc
@@ -28,7 +28,8 @@
     : ImageView(ui::ImageModel::FromVectorIcon(kSendTabToSelfIcon,
                                                ui::kColorIcon,
                                                gfx::kFaviconSize)),
-      browser_(browser_view->browser()) {
+      browser_(browser_view->browser()),
+      browser_view_(browser_view) {
   SetAccessibleName(l10n_util::GetStringUTF16(
       IDS_TOOLBAR_BUTTON_SEND_TAB_TO_SELF_BUTTON_A11Y_NAME));
   SetTooltipText(
@@ -39,13 +40,13 @@
 
   send_tab_to_self::ReceivingUiHandlerRegistry::GetInstance()
       ->GetToolbarButtonControllerForProfile(browser_->profile())
-      ->SetDelegate(this);
+      ->AddDelegate(this);
 }
 
 SendTabToSelfToolbarIconView::~SendTabToSelfToolbarIconView() {
   send_tab_to_self::ReceivingUiHandlerRegistry::GetInstance()
       ->GetToolbarButtonControllerForProfile(browser_->profile())
-      ->SetDelegate(nullptr);
+      ->RemoveDelegate(this);
 }
 
 void SendTabToSelfToolbarIconView::Show(const SendTabToSelfEntry& entry) {
@@ -63,6 +64,10 @@
   SetVisible(false);
 }
 
+bool SendTabToSelfToolbarIconView::IsActive() {
+  return browser_view_->IsActive();
+}
+
 void SendTabToSelfToolbarIconView::LogNotificationOpened() {
   send_tab_to_self::ReceivingUiHandlerRegistry::GetInstance()
       ->GetToolbarButtonControllerForProfile(browser_->profile())
diff --git a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.h b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.h
index d1f54b35..8cacb721 100644
--- a/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.h
+++ b/chrome/browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_icon_view.h
@@ -30,6 +30,7 @@
 
   // SendTabToSelfToolbarIconControllerDelegate implementation.
   void Show(const SendTabToSelfEntry& entry) override;
+  bool IsActive() override;
 
   void DismissEntry(std::string& guid);
 
@@ -40,6 +41,8 @@
  private:
   const Browser* const browser_;
 
+  const BrowserView* browser_view_;
+
   const SendTabToSelfEntry* entry_;
 };
 
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc
index b7bca06..594e4f8 100644
--- a/chrome/browser/ui/views/side_search/side_search_browser_controller.cc
+++ b/chrome/browser/ui/views/side_search/side_search_browser_controller.cc
@@ -4,35 +4,286 @@
 
 #include "chrome/browser/ui/views/side_search/side_search_browser_controller.h"
 
-#include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h"
+#include "base/bind.h"
+#include "base/strings/utf_string_conversions.h"
+#include "build/branding_buildflags.h"
+#include "chrome/app/vector_icons/vector_icons.h"
+#include "chrome/browser/ui/layout_constants.h"
+#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/side_panel.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_button.h"
+#include "chrome/grit/generated_resources.h"
+#include "components/vector_icons/vector_icons.h"
+#include "content/public/browser/navigation_handle.h"
+#include "ui/base/l10n/l10n_util.h"
+#include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/base/metadata/metadata_impl_macros.h"
+#include "ui/base/pointer/touch_ui_controller.h"
+#include "ui/views/background.h"
+#include "ui/views/controls/button/image_button.h"
+#include "ui/views/controls/button/image_button_factory.h"
+#include "ui/views/controls/highlight_path_generator.h"
+#include "ui/views/controls/separator.h"
 #include "ui/views/controls/webview/webview.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/flex_layout.h"
+#include "ui/views/layout/flex_layout_types.h"
+#include "ui/views/layout/layout_provider.h"
+#include "ui/views/layout/layout_types.h"
+#include "ui/views/view_class_properties.h"
+
+namespace {
+
+constexpr int kSidePanelWidth = 380;
+constexpr int kDefaultIconSize = 16;
+constexpr int kDefaultTouchableIconSize = 24;
+
+// Below are hardcoded color constants for the side panel. This is a UX decision
+// to ensure that the colors align with the tier 2 Google SRP which only
+// supports light mode. These are not intended to change to match the light/dark
+// system setting or custom theme colors.
+
+// White background to match the Google SRP.
+constexpr SkColor kHeaderBackgroundColor = SK_ColorWHITE;
+
+// Default light mode icon color for controls.
+constexpr SkColor kIconColor = gfx::kGoogleGrey700;
+
+// Default light mode separator color.
+constexpr SkColor kSeparatorColor = gfx::kGoogleGrey300;
+
+// Close button used in the header of the side panel. Responds appropriately to
+// touch ui changes.
+class CloseButton : public views::ImageButton {
+ public:
+  METADATA_HEADER(CloseButton);
+  explicit CloseButton(base::RepeatingClosure callback)
+      : ImageButton(std::move(callback)) {
+    views::ConfigureVectorImageButton(this);
+    views::InstallCircleHighlightPathGenerator(this);
+
+    SetBorder(views::CreateEmptyBorder(
+        gfx::Insets(views::LayoutProvider::Get()->GetDistanceMetric(
+            views::DISTANCE_CLOSE_BUTTON_MARGIN))));
+    SetID(SideSearchBrowserController::SideSearchViewID::
+              VIEW_ID_SIDE_PANEL_CLOSE_BUTTON);
+    SetAccessibleName(
+        l10n_util::GetStringUTF16(IDS_ACCNAME_SIDE_SEARCH_CLOSE_BUTTON));
+    SetTooltipText(
+        l10n_util::GetStringUTF16(IDS_TOOLTIP_SIDE_SEARCH_CLOSE_BUTTON));
+
+    UpdateIcon();
+  }
+  ~CloseButton() override = default;
+
+  void UpdateIcon() {
+    const int icon_size = ui::TouchUiController::Get()->touch_ui()
+                              ? kDefaultTouchableIconSize
+                              : kDefaultIconSize;
+    views::SetImageFromVectorIconWithColor(this, vector_icons::kCloseIcon,
+                                           icon_size, kIconColor);
+  }
+};
+
+BEGIN_METADATA(CloseButton, views::ImageButton)
+END_METADATA
+
+// Header view used to house the close control at the top of the side panel.
+class HeaderView : public views::View {
+ public:
+  METADATA_HEADER(HeaderView);
+  explicit HeaderView(base::RepeatingClosure callback)
+      : close_button_(
+            AddChildView(std::make_unique<CloseButton>(std::move(callback)))),
+        layout_(SetLayoutManager(std::make_unique<views::BoxLayout>())) {
+    SetProperty(
+        views::kFlexBehaviorKey,
+        views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
+                                 views::MaximumFlexSizeRule::kPreferred));
+    SetBackground(views::CreateSolidBackground(kHeaderBackgroundColor));
+    layout_->set_main_axis_alignment(views::BoxLayout::MainAxisAlignment::kEnd);
+    UpdateSpacing();
+  }
+  ~HeaderView() override = default;
+
+ private:
+  void UpdateSpacing() {
+    close_button_->UpdateIcon();
+    layout_->set_inside_border_insets(
+        GetLayoutInsets(LayoutInset::TOOLBAR_INTERIOR_MARGIN));
+  }
+
+  CloseButton* const close_button_;
+  views::BoxLayout* const layout_;
+
+  base::CallbackListSubscription subscription_ =
+      ui::TouchUiController::Get()->RegisterCallback(
+          base::BindRepeating(&HeaderView::UpdateSpacing,
+                              base::Unretained(this)));
+};
+
+BEGIN_METADATA(HeaderView, views::View)
+END_METADATA
+
+std::unique_ptr<views::Separator> CreateSeparator() {
+  auto separator = std::make_unique<views::Separator>();
+  separator->SetColor(kSeparatorColor);
+  return separator;
+}
+
+views::WebView* ConfigureSidePanel(views::View* side_panel,
+                                   Profile* profile,
+                                   base::RepeatingClosure callback) {
+  // BrowserViewLayout will layout the SidePanel to match the height of the
+  // content area.
+  side_panel->SetPreferredSize(gfx::Size(kSidePanelWidth, 1));
+
+  auto* layout =
+      side_panel->SetLayoutManager(std::make_unique<views::FlexLayout>());
+  layout->SetOrientation(views::LayoutOrientation::kVertical);
+  layout->SetCrossAxisAlignment(views::LayoutAlignment::kStretch);
+
+  side_panel->AddChildView(std::make_unique<HeaderView>(std::move(callback)));
+  side_panel->AddChildView(CreateSeparator());
+
+  // The WebView will fill the remaining space after the header view has been
+  // laid out.
+  auto* web_view =
+      side_panel->AddChildView(std::make_unique<views::WebView>(profile));
+  web_view->SetProperty(
+      views::kFlexBehaviorKey,
+      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
+                               views::MaximumFlexSizeRule::kUnbounded));
+
+  return web_view;
+}
+
+}  // namespace
 
 SideSearchBrowserController::SideSearchBrowserController(
     SidePanel* side_panel,
     BrowserView* browser_view)
     : side_panel_(side_panel),
       browser_view_(browser_view),
-      web_view_(side_panel_->AddChildView(
-          std::make_unique<views::WebView>(browser_view_->GetProfile()))) {
-  // TODO(tluk): Add necessary control logic.
-  side_panel_->SetVisible(true);
+      web_view_(ConfigureSidePanel(
+          side_panel,
+          browser_view_->GetProfile(),
+          base::BindRepeating(
+              &SideSearchBrowserController::SidePanelButtonPressed,
+              base::Unretained(this)))) {
+  UpdateSidePanelForContents(browser_view_->GetActiveWebContents(), nullptr);
+}
+
+SideSearchBrowserController::~SideSearchBrowserController() {
+  Observe(nullptr);
+}
+
+void SideSearchBrowserController::DidFinishNavigation(
+    content::NavigationHandle* navigation_handle) {
+  if (!navigation_handle->IsInPrimaryMainFrame() ||
+      navigation_handle->IsSameDocument() ||
+      !navigation_handle->HasCommitted()) {
+    return;
+  }
+
+  // We need to update the side panel state in response to navigations to catch
+  // cases where the user navigates to a page that should have the side panel
+  // hidden (e.g. the Google home page).
   UpdateSidePanel();
 }
 
-SideSearchBrowserController::~SideSearchBrowserController() = default;
+void SideSearchBrowserController::UpdateSidePanelForContents(
+    content::WebContents* new_contents,
+    content::WebContents* old_contents) {
+  Observe(new_contents);
+
+  // Update the state of the side panel to catch cases where we switch to a tab
+  // where the panel should be hidden (or vise versa).
+  UpdateSidePanel();
+}
+
+std::unique_ptr<ToolbarButton>
+SideSearchBrowserController::CreateToolbarButton() {
+  auto toolbar_button = std::make_unique<ToolbarButton>();
+  toolbar_button->SetAccessibleName(
+      l10n_util::GetStringUTF16(IDS_ACCNAME_SIDE_SEARCH_TOOLBAR_BUTTON));
+  toolbar_button->SetTooltipText(
+      l10n_util::GetStringUTF16(IDS_TOOLTIP_SIDE_SEARCH_TOOLBAR_BUTTON));
+
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  toolbar_button->SetVectorIcon(kGoogleGLogoIcon);
+#else
+  toolbar_button->SetVectorIcon(kWebIcon);
+#endif
+
+  toolbar_button->SetCallback(
+      base::BindRepeating(&SideSearchBrowserController::SidePanelButtonPressed,
+                          base::Unretained(this)));
+  toolbar_button->SetVisible(true);
+  toolbar_button->SetEnabled(true);
+
+  toolbar_button_ = toolbar_button.get();
+  return toolbar_button;
+}
+
+bool SideSearchBrowserController::GetSidePanelToggledOpen() const {
+  if (base::FeatureList::IsEnabled(features::kSideSearchStatePerTab)) {
+    auto* active_contents = browser_view_->GetActiveWebContents();
+    return active_contents
+               ? SideSearchTabContentsHelper::FromWebContents(active_contents)
+                     ->toggled_open()
+               : false;
+  }
+  return toggled_open_;
+}
+
+void SideSearchBrowserController::SidePanelButtonPressed() {
+  // Toggle the side panel visibility.
+  SetSidePanelToggledOpen(!GetSidePanelToggledOpen());
+}
+
+void SideSearchBrowserController::SetSidePanelToggledOpen(bool toggled_open) {
+  if (base::FeatureList::IsEnabled(features::kSideSearchStatePerTab)) {
+    if (auto* active_contents = browser_view_->GetActiveWebContents()) {
+      SideSearchTabContentsHelper::FromWebContents(active_contents)
+          ->set_toggled_open(toggled_open);
+    }
+  } else {
+    toggled_open_ = toggled_open;
+  }
+  UpdateSidePanel();
+}
 
 void SideSearchBrowserController::UpdateSidePanel() {
   auto* active_contents = browser_view_->GetActiveWebContents();
-  if (!active_contents)
+  if (!active_contents) {
+    // Ensure we reset the `web_view_`'s hosted side contents when the active
+    // tab contents is null to cover cases such as the tab being moved to
+    // another window. This is needed as the WebView's destructor will not be
+    // invoked until both the remove model update is fired in this window and
+    // the add model update is fired in the destination window.
+    web_view_->SetWebContents(nullptr);
     return;
+  }
 
   // Switch the WebContents currently in the windows side panel to the
   // WebContents associated with the active tab.
   auto* tab_contents_helper =
       SideSearchTabContentsHelper::FromWebContents(active_contents);
 
+  const bool can_show_side_panel_for_page =
+      tab_contents_helper->CanShowSidePanelForCommittedNavigation();
+  const bool will_show_side_panel =
+      can_show_side_panel_for_page && GetSidePanelToggledOpen();
+
   // The side panel contents will be created if it does not already exist.
-  web_view_->SetWebContents(tab_contents_helper->GetSidePanelContents());
+  web_view_->SetWebContents(will_show_side_panel
+                                ? tab_contents_helper->GetSidePanelContents()
+                                : nullptr);
+  side_panel_->SetVisible(will_show_side_panel);
+
+  // The toolbar button should remain visible in the toolbar as a side panel can
+  // be shown for the active tab.
+  toolbar_button_->SetVisible(can_show_side_panel_for_page);
 }
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller.h b/chrome/browser/ui/views/side_search/side_search_browser_controller.h
index 8b654f2e..0d4f372 100644
--- a/chrome/browser/ui/views/side_search/side_search_browser_controller.h
+++ b/chrome/browser/ui/views/side_search/side_search_browser_controller.h
@@ -5,28 +5,63 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_SIDE_SEARCH_SIDE_SEARCH_BROWSER_CONTROLLER_H_
 #define CHROME_BROWSER_UI_VIEWS_SIDE_SEARCH_SIDE_SEARCH_BROWSER_CONTROLLER_H_
 
+#include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "ui/views/controls/webview/unhandled_keyboard_event_handler.h"
+
 namespace views {
 class WebView;
 }  // namespace views
 
 class BrowserView;
 class SidePanel;
+class ToolbarButton;
 
 // Responsible for managing the WebContents hosted in the browser's side panel
 // for Side Search in addition to managing the state of the side panel itself.
-class SideSearchBrowserController {
+class SideSearchBrowserController : public content::WebContentsObserver {
  public:
+  enum SideSearchViewID {
+    VIEW_ID_NONE = 0,
+    VIEW_ID_SIDE_PANEL_CLOSE_BUTTON,
+  };
+
   SideSearchBrowserController(SidePanel* side_panel, BrowserView* browser_view);
   SideSearchBrowserController(const SideSearchBrowserController&) = delete;
   SideSearchBrowserController& operator=(const SideSearchBrowserController&) =
       delete;
-  virtual ~SideSearchBrowserController();
+  ~SideSearchBrowserController() override;
+
+  // content::WebContentsObserver:
+  void DidFinishNavigation(
+      content::NavigationHandle* navigation_handle) override;
+
+  void UpdateSidePanelForContents(content::WebContents* new_contents,
+                                  content::WebContents* old_contents);
+
+  std::unique_ptr<ToolbarButton> CreateToolbarButton();
+
+  views::WebView* web_view_for_testing() { return web_view_; }
 
  private:
+  // Gets and sets the toggled state of the side panel. If called with
+  // kSideSearchStatePerTab enabled this determines whether the side panel
+  // should be open for the currently active tab.
+  bool GetSidePanelToggledOpen() const;
+  void SetSidePanelToggledOpen(bool toggled_open);
+
+  // Toggles panel visibility on button press.
+  void SidePanelButtonPressed();
+
   // Updates the `side_panel_`'s visibility and updates it to host the side
   // contents associated with the currently active tab for this browser window.
   void UpdateSidePanel();
 
+  // The toggled state of the side panel (i.e. the state of the side panel
+  // as controlled by the toolbar button).
+  bool toggled_open_ = false;
+
+  ToolbarButton* toolbar_button_;
   SidePanel* const side_panel_;
   BrowserView* const browser_view_;
   views::WebView* const web_view_;
diff --git a/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc b/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc
new file mode 100644
index 0000000..7d267ed5
--- /dev/null
+++ b/chrome/browser/ui/views/side_search/side_search_browser_controller_browsertest.cc
@@ -0,0 +1,310 @@
+// Copyright 2021 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/ui/views/side_search/side_search_browser_controller.h"
+
+#include "base/feature_list.h"
+#include "base/test/scoped_feature_list.h"
+#include "build/build_config.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_tabstrip.h"
+#include "chrome/browser/ui/side_search/side_search_tab_contents_helper.h"
+#include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/side_panel.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/public/test/browser_test.h"
+#include "net/dns/mock_host_resolver.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "ui/views/controls/button/image_button.h"
+#include "ui/views/test/button_test_api.h"
+
+namespace {
+
+constexpr char kGoogleSearchURL[] = "https://www.google.com/search?q=test1";
+constexpr char kGoogleSearchHomePageURL[] = "https://www.google.com";
+constexpr char kNonGoogleURL[] = "https://www.test.com";
+
+ui::MouseEvent GetDummyEvent() {
+  return ui::MouseEvent(ui::ET_MOUSE_PRESSED, gfx::PointF(), gfx::PointF(),
+                        base::TimeTicks::Now(), 0, 0);
+}
+
+}  // namespace
+
+// TODO(tluk): Add more tests for the different side panel configurations.
+class SideSearchBrowserControllerTest : public InProcessBrowserTest {
+ public:
+  // InProcessBrowserTest:
+  void SetUp() override {
+    std::vector<base::Feature> enabled_features;
+    scoped_feature_list_.InitWithFeatures(GetEnabledFeatures(), {});
+    InProcessBrowserTest::SetUp();
+  }
+  void SetUpOnMainThread() override {
+    host_resolver()->AddRule("*", "127.0.0.1");
+    ASSERT_TRUE(embedded_test_server()->Start());
+    InProcessBrowserTest::SetUpOnMainThread();
+  }
+
+  virtual std::vector<base::Feature> GetEnabledFeatures() {
+    return {features::kSideSearch};
+  }
+
+  void ActivateTabAt(int index) {
+    browser()->tab_strip_model()->ActivateTabAt(index);
+  }
+
+  void AppendTab(const std::string& url) {
+    chrome::AddTabAt(browser(), GURL(url), -1, true);
+  }
+
+  void NavigateActiveTab(const std::string& url) {
+    ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL(url)));
+  }
+
+  void NotifyButtonClick() {
+    views::test::ButtonTestApi(side_panel_button())
+        .NotifyClick(GetDummyEvent());
+  }
+
+  void NotifyCloseButtonClick() {
+    ASSERT_TRUE(side_panel()->GetVisible());
+    views::test::ButtonTestApi(side_panel_close_button())
+        .NotifyClick(GetDummyEvent());
+  }
+
+  BrowserView* browser_view() {
+    return BrowserView::GetBrowserViewForBrowser(browser());
+  }
+
+  ToolbarButton* side_panel_button() {
+    return browser_view()->toolbar()->left_side_panel_button();
+  }
+
+  views::ImageButton* side_panel_close_button() {
+    return static_cast<views::ImageButton*>(
+        side_panel()->GetViewByID(static_cast<int>(
+            SideSearchBrowserController::VIEW_ID_SIDE_PANEL_CLOSE_BUTTON)));
+  }
+
+  SidePanel* side_panel() {
+    return browser_view()->left_aligned_side_panel_for_testing();
+  }
+
+  void NavigateToSRPAndOpenSidePanel() {
+    NavigateActiveTab(kGoogleSearchURL);
+    EXPECT_FALSE(side_panel_button()->GetVisible());
+    EXPECT_FALSE(side_panel()->GetVisible());
+
+    NavigateActiveTab(kNonGoogleURL);
+    EXPECT_TRUE(side_panel_button()->GetVisible());
+    EXPECT_FALSE(side_panel()->GetVisible());
+
+    NotifyButtonClick();
+    EXPECT_TRUE(side_panel_button()->GetVisible());
+    EXPECT_TRUE(side_panel()->GetVisible());
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest,
+                       SidePanelButtonShowsCorrectlySingleTab) {
+  // The side panel button should never be visible on the Google home page.
+  NavigateActiveTab(kGoogleSearchHomePageURL);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+
+  // If no previous Google search page has been navigated to the button should
+  // not be visible.
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+
+  // The side panel button should never be visible on the Google search page.
+  NavigateActiveTab(kGoogleSearchURL);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+
+  // The side panel button should be visible if on a non-Google page and the
+  // current tab has previously encountered a Google search page.
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+
+  // The side panel button should never be visible on the Google home page even
+  // if it has already been navigated to a Google search page.
+  NavigateActiveTab(kGoogleSearchHomePageURL);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+
+  // The side panel button should be visible if on a non-Google page and the
+  // current tab has previously encountered a Google search page.
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+}
+
+IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest,
+                       SidePanelButtonShowsCorrectlyMultipleTabs) {
+  // The side panel button should never be visible on the Google home page.
+  AppendTab(kGoogleSearchHomePageURL);
+  ActivateTabAt(1);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+
+  // Navigate to a Google search page and then to a non-Google search page. This
+  // should show the side panel button in the toolbar.
+  AppendTab(kGoogleSearchURL);
+  ActivateTabAt(2);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+
+  // Switch back to the Google search page, the side panel button should no
+  // longer be visible.
+  ActivateTabAt(1);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+
+  // When switching back to the tab on the non-Google page with a previously
+  // visited Google search page the button should be visible.
+  ActivateTabAt(2);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+}
+
+IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest,
+                       SidePanelTogglesCorrectlySingleTab) {
+  NavigateActiveTab(kGoogleSearchURL);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  // The side panel button should be visible if on a non-Google page and the
+  // current tab has previously encountered a Google search page.
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  // Toggle the side panel.
+  NotifyButtonClick();
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_TRUE(side_panel()->GetVisible());
+
+  // Toggling the button again should close the side panel.
+  NotifyButtonClick();
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+}
+
+IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest,
+                       SidePanelTogglesCorrectlyMultipleTabs) {
+  // Navigate to a Google search URL followed by a non-Google URL in two
+  // independent browser tabs such that both have the side panel ready.
+
+  // Tab 1.
+  NavigateActiveTab(kGoogleSearchURL);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  // Tab 2.
+  AppendTab(kGoogleSearchURL);
+  ActivateTabAt(1);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  // Show the side panel on Tab 2 and switch to Tab 1. The side panel should
+  // still be visible.
+  NotifyButtonClick();
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_TRUE(side_panel()->GetVisible());
+
+  ActivateTabAt(0);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_TRUE(side_panel()->GetVisible());
+
+  // Hide the side panel on Tab 1 and switch to Tab 2. The side panel should be
+  // hidden after the tab switch.
+  NotifyButtonClick();
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  ActivateTabAt(1);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+}
+
+IN_PROC_BROWSER_TEST_F(SideSearchBrowserControllerTest,
+                       CloseButtonClosesSidePanel) {
+  // The close button should be visible in the toggled state.
+  NavigateToSRPAndOpenSidePanel();
+  EXPECT_TRUE(side_panel()->GetVisible());
+  NotifyCloseButtonClick();
+}
+
+class SideSearchStatePerTabBrowserControllerTest
+    : public SideSearchBrowserControllerTest {
+ public:
+  // SideSearchBrowserControllerTest:
+  std::vector<base::Feature> GetEnabledFeatures() override {
+    auto features = SideSearchBrowserControllerTest::GetEnabledFeatures();
+    features.push_back(features::kSideSearchStatePerTab);
+    return features;
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(SideSearchStatePerTabBrowserControllerTest,
+                       SidePanelTogglesCorrectlyMultipleTabs) {
+  // Navigate to a Google search URL followed by a non-Google URL in two
+  // independent browser tabs such that both have the side panel ready. The
+  // side panel should respect the state-per-tab flag.
+
+  // Tab 1.
+  NavigateActiveTab(kGoogleSearchURL);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  // Tab 2.
+  AppendTab(kGoogleSearchURL);
+  ActivateTabAt(1);
+  EXPECT_FALSE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+  NavigateActiveTab(kNonGoogleURL);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  // Show the side panel on Tab 2 and switch to Tab 1. The side panel should
+  // not be visible for Tab 1.
+  NotifyButtonClick();
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_TRUE(side_panel()->GetVisible());
+
+  ActivateTabAt(0);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  // Show the side panel on Tab 1 and switch to Tab 2. The side panel should be
+  // still be visible for Tab 2, respecting its per-tab state.
+  NotifyButtonClick();
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_TRUE(side_panel()->GetVisible());
+
+  ActivateTabAt(1);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_TRUE(side_panel()->GetVisible());
+
+  // Close the side panel on Tab 2 and switch to Tab 1. The side panel should be
+  // still be visible for Tab 1, respecting its per-tab state.
+  NotifyButtonClick();
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_FALSE(side_panel()->GetVisible());
+
+  ActivateTabAt(0);
+  EXPECT_TRUE(side_panel_button()->GetVisible());
+  EXPECT_TRUE(side_panel()->GetVisible());
+}
diff --git a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc
index ad42142..52b3afb 100644
--- a/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc
+++ b/chrome/browser/ui/views/toolbar/chrome_labs_bubble_view_model.cc
@@ -36,7 +36,6 @@
   static const base::NoDestructor<std::vector<LabInfo>> lab_info_([]() {
     std::vector<LabInfo> lab_info;
 
-#if !defined(OS_MAC)
     // Lens Region Search
     lab_info.emplace_back(LabInfo(
         flag_descriptions::kEnableLensRegionSearchFlagId,
@@ -44,7 +43,6 @@
         l10n_util::GetStringUTF16(
             IDS_LENS_REGION_SEARCH_EXPERIMENT_DESCRIPTION),
         "chrome-labs-lens-region-search", version_info::Channel::BETA));
-#endif  // OS_MAC
 
     // Side Panel.
     lab_info.emplace_back(LabInfo(
diff --git a/chrome/browser/ui/views/toolbar/toolbar_view.cc b/chrome/browser/ui/views/toolbar/toolbar_view.cc
index 304844829..a1588dcc 100644
--- a/chrome/browser/ui/views/toolbar/toolbar_view.cc
+++ b/chrome/browser/ui/views/toolbar/toolbar_view.cc
@@ -122,6 +122,10 @@
 #include "ui/aura/window_occlusion_tracker.h"
 #endif
 
+#if BUILDFLAG(ENABLE_SIDE_SEARCH)
+#include "chrome/browser/ui/views/side_search/side_search_browser_controller.h"
+#endif  // BUILDFLAG(ENABLE_SIDE_SEARCH)
+
 using base::UserMetricsAction;
 using content::WebContents;
 
@@ -297,6 +301,16 @@
   forward_ = AddChildView(std::move(forward));
   reload_ = AddChildView(std::move(reload));
   home_ = AddChildView(std::move(home));
+
+#if BUILDFLAG(ENABLE_SIDE_SEARCH)
+  // The side search button (if enabled) should sit between the location bar and
+  // the other navigation buttons.
+  if (browser_view_->side_search_controller()) {
+    left_side_panel_button_ = AddChildView(
+        browser_view_->side_search_controller()->CreateToolbarButton());
+  }
+#endif  // BUILDFLAG(ENABLE_SIDE_SEARCH)
+
   location_bar_ = AddChildView(std::move(location_bar));
 
   if (extensions_container)
diff --git a/chrome/browser/ui/views/webauthn/webauthn_bubble_view.cc b/chrome/browser/ui/views/webauthn/webauthn_bubble_view.cc
index 0af0304..e3a6a0a8 100644
--- a/chrome/browser/ui/views/webauthn/webauthn_bubble_view.cc
+++ b/chrome/browser/ui/views/webauthn/webauthn_bubble_view.cc
@@ -6,13 +6,10 @@
 
 #include <memory>
 
-#include "base/callback.h"
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
 #include "chrome/browser/ui/views/frame/toolbar_button_provider.h"
-#include "chrome/browser/ui/views/webauthn/hover_list_view.h"
-#include "chrome/browser/ui/webauthn/account_hover_list_model.h"
 #include "chrome/browser/ui/webauthn/webauthn_ui_helpers.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/strings/grit/components_strings.h"
@@ -26,14 +23,12 @@
 // static
 WebAuthnBubbleView* WebAuthnBubbleView::Create(
     const std::string& relying_party_id,
-    std::vector<device::PublicKeyCredentialUserEntity> users,
-    SelectedCallback selected_callback,
     content::WebContents* web_contents) {
   Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
   ToolbarButtonProvider* button_provider =
       BrowserView::GetBrowserViewForBrowser(browser)->toolbar_button_provider();
   auto bubble_view = std::make_unique<WebAuthnBubbleView>(
-      relying_party_id, std::move(users), std::move(selected_callback),
+      relying_party_id,
       button_provider->GetAnchorView(PageActionIconType::kWebAuthn),
       web_contents);
   WebAuthnBubbleView* weak_bubble_view = bubble_view.get();
@@ -43,16 +38,11 @@
   return weak_bubble_view;
 }
 
-WebAuthnBubbleView::WebAuthnBubbleView(
-    const std::string& relying_party_id,
-    std::vector<device::PublicKeyCredentialUserEntity> users,
-    SelectedCallback selected_callback,
-    views::View* anchor_view,
-    content::WebContents* web_contents)
+WebAuthnBubbleView::WebAuthnBubbleView(const std::string& relying_party_id,
+                                       views::View* anchor_view,
+                                       content::WebContents* web_contents)
     : LocationBarBubbleDelegateView(anchor_view, web_contents),
-      relying_party_id_(relying_party_id),
-      users_(std::move(users)),
-      selected_callback_(std::move(selected_callback)) {
+      relying_party_id_(relying_party_id) {
   SetShowCloseButton(true);
   SetButtons(ui::DIALOG_BUTTON_CANCEL);
   SetButtonLabel(ui::DIALOG_BUTTON_CANCEL,
@@ -65,33 +55,21 @@
 
 std::u16string WebAuthnBubbleView::GetWindowTitle() const {
   // TODO(crbug.com/1179014): go through ux review and i18n this string.
-  return users_.empty() ? u"Sign in with your security key"
-                        : u"Choose an account to sign in";
+  return u"Sign in with your security key";
 }
 
 void WebAuthnBubbleView::Init() {
   SetLayoutManager(std::make_unique<views::FillLayout>());
 
-  if (users_.empty()) {
-    // TODO(crbug.com/1179014): go through ux review and i18n this string.
-    std::u16string label_text = base::ReplaceStringPlaceholders(
-        u"To sign in to $1 with your security key, insert it and tap it",
-        webauthn_ui_helpers::RpIdToElidedHost(relying_party_id_, fixed_width()),
-        /*offset=*/nullptr);
-    auto label = std::make_unique<views::Label>(
-        label_text, views::style::CONTEXT_DIALOG_BODY_TEXT,
-        views::style::STYLE_SECONDARY);
-    label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
-    label->SetMultiLine(true);
-    AddChildView(std::move(label));
-    return;
-  }
-
-  AddChildView(std::make_unique<HoverListView>(
-      std::make_unique<AccountHoverListModel>(&users_, this)));
-}
-
-void WebAuthnBubbleView::OnItemSelected(int index) {
-  std::move(selected_callback_).Run(index);
-  CloseBubble();
+  // TODO(crbug.com/1179014): go through ux review and i18n this string.
+  std::u16string label_text = base::ReplaceStringPlaceholders(
+      u"To sign in to $1 with your security key, insert it and tap it",
+      webauthn_ui_helpers::RpIdToElidedHost(relying_party_id_, fixed_width()),
+      /*offset=*/nullptr);
+  auto label = std::make_unique<views::Label>(
+      label_text, views::style::CONTEXT_DIALOG_BODY_TEXT,
+      views::style::STYLE_SECONDARY);
+  label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+  label->SetMultiLine(true);
+  AddChildView(std::move(label));
 }
diff --git a/chrome/browser/ui/views/webauthn/webauthn_bubble_view.h b/chrome/browser/ui/views/webauthn/webauthn_bubble_view.h
index 0eda0d7..e683b48 100644
--- a/chrome/browser/ui/views/webauthn/webauthn_bubble_view.h
+++ b/chrome/browser/ui/views/webauthn/webauthn_bubble_view.h
@@ -7,10 +7,6 @@
 
 #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h"
 
-#include "base/callback_forward.h"
-#include "chrome/browser/ui/webauthn/account_hover_list_model.h"
-#include "device/fido/public_key_credential_user_entity.h"
-
 namespace content {
 class WebContents;
 }  // namespace content
@@ -18,26 +14,14 @@
 // A bubble that appears near the omnibar when the user clicks a
 // |WebAuthnIconView|, instructing the user that they can insert and tap their
 // security key to log-in to the website.
-//
-// If there are available platform authenticator credentials, the user is
-// presented with a list to choose from instead.
-class WebAuthnBubbleView : public LocationBarBubbleDelegateView,
-                           public AccountHoverListModel::Delegate {
+class WebAuthnBubbleView : public LocationBarBubbleDelegateView {
  public:
-  // Called when an account has been selected for the available platform
-  // authenticator credentials case.
-  using SelectedCallback = base::OnceCallback<void(size_t)>;
-
   // Creates a WebAuthnBubbleView owned by its widget.
   static WebAuthnBubbleView* Create(
       const std::string& relying_party_id,
-      std::vector<device::PublicKeyCredentialUserEntity> users,
-      SelectedCallback selected_callback,
       content::WebContents* web_contents);
 
   WebAuthnBubbleView(const std::string& relying_party_id,
-                     std::vector<device::PublicKeyCredentialUserEntity> users,
-                     base::OnceCallback<void(size_t)> selected_callback,
                      views::View* anchor_view,
                      content::WebContents* web_contents);
   ~WebAuthnBubbleView() override;
@@ -49,12 +33,7 @@
   void Init() override;
 
  private:
-  // AccountHoverListModel::Delegate:
-  void OnItemSelected(int index) override;
-
   std::string relying_party_id_;
-  std::vector<device::PublicKeyCredentialUserEntity> users_;
-  SelectedCallback selected_callback_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_WEBAUTHN_WEBAUTHN_BUBBLE_VIEW_H_
diff --git a/chrome/browser/ui/views/webauthn/webauthn_icon_view.cc b/chrome/browser/ui/views/webauthn/webauthn_icon_view.cc
index 8842a77a..5f618bd 100644
--- a/chrome/browser/ui/views/webauthn/webauthn_icon_view.cc
+++ b/chrome/browser/ui/views/webauthn/webauthn_icon_view.cc
@@ -6,7 +6,6 @@
 
 #include <utility>
 
-#include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "chrome/app/chrome_command_ids.h"
 #include "chrome/app/vector_icons/vector_icons.h"
@@ -70,9 +69,6 @@
   if (dialog_models_.find(web_contents) == dialog_models_.end()) {
     dialog_model->AddObserver(this);
     dialog_models_.insert({web_contents, dialog_model});
-    if (!dialog_model->users().empty()) {
-      ExecuteCommand(EXECUTE_SOURCE_MOUSE);
-    }
   }
 }
 
@@ -83,11 +79,8 @@
   }
   content::WebContents* web_contents = GetWebContents();
   AuthenticatorRequestDialogModel* model = dialog_models_.at(web_contents);
-  webauthn_bubble_ = WebAuthnBubbleView::Create(
-      model->relying_party_id(), model->users(),
-      base::BindOnce(&AuthenticatorRequestDialogModel::OnAccountSelected,
-                     model->GetWeakPtr()),
-      web_contents);
+  webauthn_bubble_ =
+      WebAuthnBubbleView::Create(model->relying_party_id(), web_contents);
   webauthn_bubble_->GetWidget()->AddObserver(this);
 }
 
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
index 37b2fb7..a6981256 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.cc
@@ -5,10 +5,12 @@
 #include "chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h"
 
 #include "ash/public/cpp/system_tray.h"
+#include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "chrome/browser/chromeos/phonehub/phone_hub_manager_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chromeos/components/multidevice/logging/logging.h"
+#include "chromeos/components/phonehub/camera_roll_item.h"
 #include "chromeos/components/phonehub/fake_phone_hub_manager.h"
 #include "chromeos/components/phonehub/pref_names.h"
 #include "components/prefs/pref_service.h"
@@ -24,6 +26,7 @@
 const int kIconSize = 16;
 const int kContactImageSize = 80;
 const int kSharedImageSize = 400;
+const int kCameraRollThumbnailSize = 96;
 
 // Fake image types used for fields that require gfx::Image().
 enum class ImageType {
@@ -119,6 +122,13 @@
   metadatas.push_back(metadata);
 }
 
+const SkBitmap RGB_Bitmap(U8CPU r, U8CPU g, U8CPU b, int size) {
+  SkBitmap bitmap;
+  bitmap.allocN32Pixels(size, size);
+  bitmap.eraseARGB(255, r, g, b);
+  return bitmap;
+}
+
 }  // namespace
 
 MultidevicePhoneHubHandler::MultidevicePhoneHubHandler() = default;
@@ -198,6 +208,11 @@
       base::BindRepeating(&MultidevicePhoneHubHandler::
                               HandleResetHasNotificationSetupUiBeenDismissed,
                           base::Unretained(this)));
+
+  web_ui()->RegisterDeprecatedMessageCallback(
+      "setCameraRoll",
+      base::BindRepeating(&MultidevicePhoneHubHandler::HandleSetCameraRoll,
+                          base::Unretained(this)));
 }
 
 void MultidevicePhoneHubHandler::OnJavascriptDisallowed() {
@@ -548,5 +563,39 @@
   PA_LOG(VERBOSE) << "Reset kHasDismissedSetupRequiredUi pref";
 }
 
+void MultidevicePhoneHubHandler::HandleSetCameraRoll(
+    const base::ListValue* args) {
+  const base::DictionaryValue* camera_roll_dict = nullptr;
+  CHECK(args->GetDictionary(0, &camera_roll_dict));
+
+  int number_of_thumbnails;
+  CHECK(camera_roll_dict->GetInteger("numberOfThumbnails",
+                                     &number_of_thumbnails));
+
+  if (number_of_thumbnails == 0) {
+    fake_phone_hub_manager_->fake_camera_roll_manager()->ClearCurrentItems();
+  } else {
+    std::vector<phonehub::CameraRollItem> items;
+    // Create items in descending key order
+    for (int i = number_of_thumbnails; i > 0; --i) {
+      phonehub::proto::CameraRollItemMetadata metadata;
+      metadata.set_key(base::NumberToString(i));
+      metadata.set_mime_type("image/jpeg");
+      metadata.set_last_modified_millis(1577865600 + i);
+      metadata.set_file_size_bytes(123456);
+      metadata.set_file_name("fake_file_" + base::NumberToString(i) + ".jpg");
+
+      gfx::Image thumbnail = gfx::Image::CreateFrom1xBitmap(
+          RGB_Bitmap(255 - i * 12, 63 + i * 12, 255, kCameraRollThumbnailSize));
+
+      items.emplace_back(metadata, thumbnail);
+    }
+    fake_phone_hub_manager_->fake_camera_roll_manager()->SetCurrentItems(items);
+  }
+
+  PA_LOG(VERBOSE) << "Setting Camera Roll to " << number_of_thumbnails
+                  << " thumbnails";
+}
+
 }  // namespace multidevice
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h
index 07a1242a..1b72153 100644
--- a/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h
+++ b/chrome/browser/ui/webui/chromeos/multidevice_internals/multidevice_internals_phone_hub_handler.h
@@ -74,6 +74,7 @@
   void HandleResetShouldShowOnboardingUi(const base::ListValue* args);
   void HandleResetHasNotificationSetupUiBeenDismissed(
       const base::ListValue* args);
+  void HandleSetCameraRoll(const base::ListValue* args);
 
   void AddObservers();
   void RemoveObservers();
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
index fe870de3..1e9e0d2 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/feature_list.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/time/time.h"
@@ -205,6 +206,8 @@
 }
 
 void HistoryClustersHandler::QueryClusters(mojom::QueryParamsPtr query_params) {
+  base::TimeTicks query_start_time = base::TimeTicks::Now();
+
   const std::string& query = query_params->query;
   const size_t max_count = query_params->max_count;
   base::Time end_time;
@@ -232,7 +235,8 @@
       base::BindOnce(&QueryClustersResultToMojom, profile_, query,
                      query_params->end_time.has_value())
           .Then(base::BindOnce(&HistoryClustersHandler::OnClustersQueryResult,
-                               weak_ptr_factory_.GetWeakPtr())),
+                               weak_ptr_factory_.GetWeakPtr(),
+                               query_start_time)),
       &query_task_tracker_);
 }
 
@@ -275,8 +279,13 @@
 }
 
 void HistoryClustersHandler::OnClustersQueryResult(
+    base::TimeTicks query_start_time,
     mojom::QueryResultPtr query_result) {
   page_->OnClustersQueryResult(std::move(query_result));
+
+  // Log metrics after delivering the results to the page.
+  base::TimeDelta service_latency = base::TimeTicks::Now() - query_start_time;
+  base::UmaHistogramTimes("History.Clusters.ServiceLatency", service_latency);
 }
 
 void HistoryClustersHandler::OnVisitsRemoved(
diff --git a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
index 9922f30..4cc5b48f 100644
--- a/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
+++ b/chrome/browser/ui/webui/history_clusters/history_clusters_handler.h
@@ -51,8 +51,10 @@
 
  private:
   // Called with the result of querying clusters. Subsequently, `query_result`
-  // is sent to the JS to update the UI.
-  void OnClustersQueryResult(mojom::QueryResultPtr query_result);
+  // is sent to the JS to update the UI. `query_start_time` is also passed to
+  // allow for performance logging.
+  void OnClustersQueryResult(base::TimeTicks query_start_time,
+                             mojom::QueryResultPtr query_result);
   // Called with the set of removed visits. Subsequently, `visits` is sent to
   // the JS to update the UI.
   void OnVisitsRemoved(std::vector<mojom::URLVisitPtr> visits);
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
index be479a47..60c4c6ab 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -354,10 +354,6 @@
 }
 
 void AuthenticatorRequestDialogModel::OnRequestTimeout() {
-  if (current_step_ == Step::kLocationBarBubble) {
-    Cancel();
-    return;
-  }
   // The request may time out while the UI shows a different error.
   if (!is_request_complete()) {
     SetCurrentStep(Step::kTimedOut);
@@ -410,7 +406,11 @@
   if (use_location_bar_bubble_) {
     // Do not show a page-modal retry error sheet if the user cancelled out of
     // their platform authenticator while displaying the location bar bubble UI.
-    Cancel();
+    // Instead, retry silently.
+    // TODO(nsatragno): we should retry for cross platform authenticators as
+    // well. However, hiding the dialog after it's been shown locks the page
+    // (see crbug.com/1247338).
+    StartOver();
     return;
   }
   SetCurrentStep(Step::kErrorInternalUnrecognized);
@@ -518,14 +518,6 @@
 }
 
 void AuthenticatorRequestDialogModel::OnAccountSelected(size_t index) {
-  if (ephemeral_state_.responses_.empty()) {
-    // An account has been pre-selected from the conditional UI prompt.
-    preselected_account_ = std::move(ephemeral_state_.users_.at(index));
-    ephemeral_state_.users_.clear();
-    HideDialogAndDispatchToPlatformAuthenticator();
-    return;
-  }
-
   if (!selection_callback_) {
     // It's possible that the user could activate the dialog more than once
     // before the Webauthn request is completed and its torn down.
@@ -539,6 +531,19 @@
   std::move(selection_callback_).Run(std::move(response));
 }
 
+void AuthenticatorRequestDialogModel::OnAccountPreselected(
+    const std::vector<uint8_t>& id) {
+  for (const auto& account : users()) {
+    if (account.id == id) {
+      preselected_account_ = std::move(account);
+      ephemeral_state_.users_.clear();
+      HideDialogAndDispatchToPlatformAuthenticator();
+      return;
+    }
+  }
+  NOTREACHED();
+}
+
 void AuthenticatorRequestDialogModel::SetSelectedAuthenticatorForTesting(
     AuthenticatorReference test_authenticator) {
   ephemeral_state_.selected_authenticator_id_ =
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h
index 3048716..856940a 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model.h
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -446,6 +446,10 @@
   // |responses()|.
   void OnAccountSelected(size_t index);
 
+  // Called when an account from |ephemeral_state_.users_| is selected from the
+  // Conditional UI prompt.
+  void OnAccountPreselected(const std::vector<uint8_t>& id);
+
   void SetSelectedAuthenticatorForTesting(AuthenticatorReference authenticator);
 
   base::span<const Mechanism> mechanisms() const;
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
index 20f1b66..6ae5b10 100644
--- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
+++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -651,9 +651,9 @@
   EXPECT_TRUE(model.should_dialog_be_hidden());
   EXPECT_EQ(num_called, 0);
 
-  // After selecting an account, the request should be dispatched to the
+  // After preselecting an account, the request should be dispatched to the
   // platform authenticator.
-  model.OnAccountSelected(0);
+  model.OnAccountPreselected({1, 2, 3, 4});
   task_environment_.FastForwardUntilNoTasksRemain();
   EXPECT_EQ(num_called, 1);
 
diff --git a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java
index 96e7740..c376d350 100644
--- a/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java
+++ b/chrome/browser/xsurface/android/java/src/org/chromium/chrome/browser/xsurface/SurfaceScopeDependencyProvider.java
@@ -176,44 +176,4 @@
     default boolean isActivityLoggingEnabled() {
         return false;
     }
-
-    // TODO(iwells): Remove the methods below when they're no longer used.
-    /** Returns the account name of the signed-in user, or the empty string. */
-    @Deprecated
-    default String getAccountName() {
-        return "";
-    }
-
-    /** Returns the client instance id for this chrome. */
-    @Deprecated
-    default String getClientInstanceId() {
-        return "";
-    }
-
-    /** Returns the collection of currently active experiment ids. */
-    @Deprecated
-    default int[] getExperimentIds() {
-        return new int[0];
-    }
-
-    /** Returns the signed-out session id */
-    @Deprecated
-    default String getSignedOutSessionId() {
-        return "";
-    }
-
-    /**
-     * Stores a view FeedAction for eventual upload. 'data' is a serialized FeedAction protobuf
-     * message.
-     */
-    @Deprecated
-    default void processViewAction(byte[] data) {}
-
-    /**
-     * Reports whether the visibility log upload was successful.
-     *
-     * @param success - whether the upload was successful
-     */
-    @Deprecated
-    default void reportOnUploadVisibilityLog(boolean success) {}
 }
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index 213170e9..49c3a210 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1632398378-b8dc256122e40c5b17b23bc8b64828ce23a2ea56.profdata
+chrome-linux-main-1632419984-678da51b22078c3216dd3c6b35bf961963fd8ebc.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 1c8c469..f5083da 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1632398378-99db40e11b1942501d614c8a6841e6bdbda6b6ad.profdata
+chrome-mac-main-1632419984-2753829d6c68ebb64dc4ba8688838157066c96b3.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 59b4e33b..b1ee1694 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1632408842-8968faa2f3b167eda47a9d899acbe9c5363d2c8d.profdata
+chrome-win32-main-1632419984-487129f3332d781d1e2c38cec12ebd41e641b498.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 7e0cee2f..190e410 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1632408842-304554f881e1ad7635710ff36be9bf9c0ae02250.profdata
+chrome-win64-main-1632419984-1922ebbc71b8a72ee3eea7730c287394dbd19ca4.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 688f7bf4..01287f2 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -87,6 +87,22 @@
 #endif
 };
 
+#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
+    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+// Enables or disables the Autofill survey triggered by opening a prompt to
+// save address info.
+const base::Feature kAutofillAddressSurvey{"AutofillAddressSurvey",
+                                           base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables or disables the Autofill survey triggered by opening a prompt to
+// save credit card info.
+const base::Feature kAutofillCardSurvey{"AutofillCardSurvey",
+                                        base::FEATURE_DISABLED_BY_DEFAULT};
+// Enables or disables the Autofill survey triggered by opening a prompt to
+// save password info.
+const base::Feature kAutofillPasswordSurvey{"AutofillPasswordSurvey",
+                                            base::FEATURE_DISABLED_BY_DEFAULT};
+#endif
+
 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
 // Enables the Restart background mode optimization. When all Chrome UI is
 // closed and it goes in the background, allows to restart the browser to
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h
index 4c670c186..7b3fb7c 100644
--- a/chrome/common/chrome_features.h
+++ b/chrome/common/chrome_features.h
@@ -72,6 +72,16 @@
 
 COMPONENT_EXPORT(CHROME_FEATURES) extern const base::Feature kAsyncDns;
 
+#if defined(OS_WIN) || defined(OS_MAC) || defined(OS_LINUX) || \
+    defined(OS_CHROMEOS) || defined(OS_FUCHSIA)
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kAutofillAddressSurvey;
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kAutofillCardSurvey;
+COMPONENT_EXPORT(CHROME_FEATURES)
+extern const base::Feature kAutofillPasswordSurvey;
+#endif
+
 #if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_CHROMEOS)
 COMPONENT_EXPORT(CHROME_FEATURES)
 extern const base::Feature kBackgroundModeAllowRestart;
diff --git a/chrome/common/extensions/api/_manifest_features.json b/chrome/common/extensions/api/_manifest_features.json
index a07cf535..9dd28cf 100644
--- a/chrome/common/extensions/api/_manifest_features.json
+++ b/chrome/common/extensions/api/_manifest_features.json
@@ -189,7 +189,10 @@
   "options_page": {
     "channel": "stable",
     "extension_types": [
-      "extension", "legacy_packaged_app", "hosted_app"
+      "extension",
+      "legacy_packaged_app",
+      "hosted_app",
+      "chromeos_system_extension"
     ]
   },
   "page_action": {
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 8fcd7538..fe10937 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3936,6 +3936,10 @@
       ]
     }
 
+    if (enable_side_search) {
+      sources += [ "../browser/ui/views/side_search/side_search_browser_controller_browsertest.cc" ]
+    }
+
     if (enable_spellcheck) {
       sources +=
           [ "../browser/site_isolation/spellcheck_per_process_browsertest.cc" ]
@@ -5058,6 +5062,13 @@
     ]
   }
 
+  if (enable_side_search) {
+    sources += [
+      "../browser/ui/side_search/side_search_side_contents_helper_unittest.cc",
+      "../browser/ui/side_search/side_search_tab_contents_helper_unittest.cc",
+    ]
+  }
+
   configs += [ "//build/config:precompiled_headers" ]
   configs += [ ":disable_thinlto_cache_flags" ]
 
@@ -7750,6 +7761,18 @@
     ]
     deps += [ "//chrome/browser/lens/region_search" ]
   }
+
+  if (is_fuchsia) {
+    data += [ "//testing/buildbot/filters/fuchsia.unit_tests.filter" ]
+
+    additional_manifest_fragments = [
+      "//build/config/fuchsia/test/font_capabilities.test-cmx",
+
+      # TODO(crbug.com/1185811): Figure out why jit_capabilities is needed.
+      "//build/config/fuchsia/test/jit_capabilities.test-cmx",
+      "//build/config/fuchsia/test/network_capabilities.test-cmx",
+    ]
+  }
 }
 
 static_library("test_support_unit") {
diff --git a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension.json b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension.json
index d1984d3..0d6b990 100644
--- a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension.json
+++ b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension.json
@@ -18,5 +18,6 @@
       "matches": [
         "http://www.google.com/*"
       ]
-    }
+    },
+    "options_page": "options.html"
 }
diff --git a/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js b/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js
index c320376b..a9bc4765 100644
--- a/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js
+++ b/chrome/test/data/webui/chromeos/diagnostics/routine_result_entry_test.js
@@ -109,6 +109,17 @@
     return routineLinkContainer;
   }
 
+  /**
+   * Returns the span wrapping the failure reason text.
+   * @return {!HTMLSpanElement}
+   */
+  function getFailedTestContainer() {
+    const failedTestContainer = /** @type {!HTMLSpanElement} */ (
+        routineResultEntryElement.$$('#failedTestText'));
+    assertTrue(!!failedTestContainer);
+    return failedTestContainer;
+  }
+
   test('ElementRendered', () => {
     return initializeRoutineResultEntry().then(() => {
       // Verify the element rendered.
@@ -255,4 +266,17 @@
       assertTrue(isVisible(getRoutineLinkContainer()));
     });
   });
+
+  test('NetworkRoutineHasCorrectFailureMessage', () => {
+    const item = new RoutineGroup(
+        [RoutineType.kLanConnectivity], 'lanConnectivityRoutineText');
+    item.failedTest = RoutineType.kLanConnectivity;
+    return initializeEntryWithItem(item, true).then(() => {
+      // Span should not be hidden
+      assertTrue(isVisible(getFailedTestContainer()));
+      dx_utils.assertElementContainsText(
+          getFailedTestContainer(),
+          loadTimeData.getString('lanConnectivityFailedText'));
+    });
+  });
 }
diff --git a/chromecast/app/android/cast_crash_reporter_client_android.h b/chromecast/app/android/cast_crash_reporter_client_android.h
index a190e95..606ad06 100644
--- a/chromecast/app/android/cast_crash_reporter_client_android.h
+++ b/chromecast/app/android/cast_crash_reporter_client_android.h
@@ -17,6 +17,12 @@
     : public crash_reporter::CrashReporterClient {
  public:
   explicit CastCrashReporterClientAndroid(const std::string& process_type);
+
+  CastCrashReporterClientAndroid(const CastCrashReporterClientAndroid&) =
+      delete;
+  CastCrashReporterClientAndroid& operator=(
+      const CastCrashReporterClientAndroid&) = delete;
+
   ~CastCrashReporterClientAndroid() override;
 
   // Return the path to a directory of MIME-encoded crash reports.
@@ -35,8 +41,6 @@
 
  private:
   std::string process_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastCrashReporterClientAndroid);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/app/cast_main_delegate.cc b/chromecast/app/cast_main_delegate.cc
index 7f234af7..e07989e8 100644
--- a/chromecast/app/cast_main_delegate.cc
+++ b/chromecast/app/cast_main_delegate.cc
@@ -10,6 +10,7 @@
 
 #include "base/command_line.h"
 #include "base/cpu.h"
+#include "base/debug/leak_annotations.h"
 #include "base/files/file.h"
 #include "base/files/file_enumerator.h"
 #include "base/files/file_util.h"
@@ -213,19 +214,28 @@
   DCHECK(cast_feature_list_creator_);
 
 #if !defined(OS_ANDROID)
-  // PrefService requires home directory to be created before the pref
-  // store can be initialized properly.
+  // PrefService requires the home directory to be created before the pref store
+  // can be initialized properly.
   base::FilePath home_dir;
   CHECK(base::PathService::Get(DIR_CAST_HOME, &home_dir));
   CHECK(base::CreateDirectory(home_dir));
 #endif  // !defined(OS_ANDROID)
 
-  // The |FieldTrialList| is a dependency of the feature list. In tests, it
-  // gets constructed as part of the test suite.
+  // TODO(crbug/1249485): If we're able to create the MetricsStateManager
+  // earlier, clean up the below if and else blocks and call
+  // MetricsStateManager::InstantiateFieldTrialList().
+  //
+  // The FieldTrialList is a dependency of the feature list. In tests, it is
+  // constructed as part of the test suite.
   if (is_running_tests) {
     DCHECK(base::FieldTrialList::GetInstance());
   } else {
-    field_trial_list_ = std::make_unique<base::FieldTrialList>(nullptr);
+    // This is intentionally leaked since it needs to live for the duration of
+    // the browser process and there's no benefit to cleaning it up at exit.
+    base::FieldTrialList* leaked_field_trial_list =
+        new base::FieldTrialList(nullptr);
+    ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list);
+    ignore_result(leaked_field_trial_list);
   }
 
   // Initialize the base::FeatureList and the PrefService (which it depends on),
diff --git a/chromecast/app/cast_main_delegate.h b/chromecast/app/cast_main_delegate.h
index 47ef0e3..c555ad931 100644
--- a/chromecast/app/cast_main_delegate.h
+++ b/chromecast/app/cast_main_delegate.h
@@ -12,10 +12,6 @@
 #include "chromecast/common/cast_content_client.h"
 #include "content/public/app/content_main_delegate.h"
 
-namespace base {
-class FieldTrialList;
-}  // namespace base
-
 namespace content {
 class BrowserMainRunner;
 }  // namespace content
@@ -35,6 +31,10 @@
 class CastMainDelegate : public content::ContentMainDelegate {
  public:
   CastMainDelegate();
+
+  CastMainDelegate(const CastMainDelegate&) = delete;
+  CastMainDelegate& operator=(const CastMainDelegate&) = delete;
+
   ~CastMainDelegate() override;
 
   // content::ContentMainDelegate implementation:
@@ -68,15 +68,7 @@
   std::unique_ptr<content::BrowserMainRunner> browser_runner_;
 #endif  // defined(OS_ANDROID)
 
-  // |field_trial_list_| is a singleton-like that needs to live for as long as
-  // anything uses it. It is accessible through |FieldTrialList| static methods,
-  // but gives no warning if those methods are called without some instance
-  // existing somewhere.
-  std::unique_ptr<base::FieldTrialList> field_trial_list_;
-
   std::unique_ptr<CastFeatureListCreator> cast_feature_list_creator_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastMainDelegate);
 };
 
 }  // namespace shell
diff --git a/chromecast/app/cast_test_launcher.cc b/chromecast/app/cast_test_launcher.cc
index fdef3c1..b6e66d3 100644
--- a/chromecast/app/cast_test_launcher.cc
+++ b/chromecast/app/cast_test_launcher.cc
@@ -24,6 +24,10 @@
 class CastTestLauncherDelegate : public content::TestLauncherDelegate {
  public:
   CastTestLauncherDelegate() {}
+
+  CastTestLauncherDelegate(const CastTestLauncherDelegate&) = delete;
+  CastTestLauncherDelegate& operator=(const CastTestLauncherDelegate&) = delete;
+
   ~CastTestLauncherDelegate() override {}
 
   int RunTestSuite(int argc, char** argv) override {
@@ -39,9 +43,6 @@
     return new CastMainDelegate();
   }
 #endif  // defined(OS_ANDROID)
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastTestLauncherDelegate);
 };
 
 }  // namespace shell
diff --git a/chromecast/app/linux/cast_crash_reporter_client.h b/chromecast/app/linux/cast_crash_reporter_client.h
index 127e086..286a7b9 100644
--- a/chromecast/app/linux/cast_crash_reporter_client.h
+++ b/chromecast/app/linux/cast_crash_reporter_client.h
@@ -19,6 +19,10 @@
   static void InitCrashReporter(const std::string& process_type);
 
   CastCrashReporterClient();
+
+  CastCrashReporterClient(const CastCrashReporterClient&) = delete;
+  CastCrashReporterClient& operator=(const CastCrashReporterClient&) = delete;
+
   ~CastCrashReporterClient() override;
 
   // crash_reporter::CrashReporterClient implementation:
@@ -28,8 +32,6 @@
 
  private:
   static uint64_t GetProcessStartTime();
-
-  DISALLOW_COPY_AND_ASSIGN(CastCrashReporterClient);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/alarm_manager.h b/chromecast/base/alarm_manager.h
index 7060e918..bda6bba9 100644
--- a/chromecast/base/alarm_manager.h
+++ b/chromecast/base/alarm_manager.h
@@ -37,6 +37,10 @@
   // Construct and start the alarm manager. The clock poller will run on the
   // caller's thread.
   AlarmManager();
+
+  AlarmManager(const AlarmManager&) = delete;
+  AlarmManager& operator=(const AlarmManager&) = delete;
+
   ~AlarmManager();
 
   // For testing only. Allows setting a fake clock and using a custom task
@@ -67,6 +71,10 @@
     AlarmInfo(base::OnceClosure task,
               base::Time time,
               scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+
+    AlarmInfo(const AlarmInfo&) = delete;
+    AlarmInfo& operator=(const AlarmInfo&) = delete;
+
     ~AlarmInfo();
 
     void PostTask();
@@ -77,7 +85,6 @@
     base::OnceClosure task_;
     const base::Time time_;
     const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-    DISALLOW_COPY_AND_ASSIGN(AlarmInfo);
   };
 
   // Check if an alarm should fire.
@@ -110,8 +117,6 @@
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
 
   base::WeakPtrFactory<AlarmManager> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlarmManager);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/android/system_time_change_notifier_android.h b/chromecast/base/android/system_time_change_notifier_android.h
index 304fa0a..44b5d51 100644
--- a/chromecast/base/android/system_time_change_notifier_android.h
+++ b/chromecast/base/android/system_time_change_notifier_android.h
@@ -14,6 +14,12 @@
 class SystemTimeChangeNotifierAndroid : public SystemTimeChangeNotifier {
  public:
   SystemTimeChangeNotifierAndroid();
+
+  SystemTimeChangeNotifierAndroid(const SystemTimeChangeNotifierAndroid&) =
+      delete;
+  SystemTimeChangeNotifierAndroid& operator=(
+      const SystemTimeChangeNotifierAndroid&) = delete;
+
   ~SystemTimeChangeNotifierAndroid() override;
 
   // Called from Java.
@@ -22,8 +28,6 @@
 
  private:
   base::android::ScopedJavaGlobalRef<jobject> java_notifier_;
-
-  DISALLOW_COPY_AND_ASSIGN(SystemTimeChangeNotifierAndroid);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/cast_features_unittest.cc b/chromecast/base/cast_features_unittest.cc
index 4133431f..70fe1d80 100644
--- a/chromecast/base/cast_features_unittest.cc
+++ b/chromecast/base/cast_features_unittest.cc
@@ -25,6 +25,10 @@
 class CastFeaturesTest : public testing::Test {
  public:
   CastFeaturesTest() {}
+
+  CastFeaturesTest(const CastFeaturesTest&) = delete;
+  CastFeaturesTest& operator=(const CastFeaturesTest&) = delete;
+
   ~CastFeaturesTest() override {}
 
   // testing::Test implementation:
@@ -40,8 +44,6 @@
 
  private:
   std::unique_ptr<base::FeatureList> original_feature_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastFeaturesTest);
 };
 
 TEST_F(CastFeaturesTest, EnableDisableMultipleBooleanFeatures) {
diff --git a/chromecast/base/cast_sys_info_android.h b/chromecast/base/cast_sys_info_android.h
index 8d6ea086..91ce91a 100644
--- a/chromecast/base/cast_sys_info_android.h
+++ b/chromecast/base/cast_sys_info_android.h
@@ -22,6 +22,10 @@
 class CastSysInfoAndroid : public CastSysInfo {
  public:
   CastSysInfoAndroid();
+
+  CastSysInfoAndroid(const CastSysInfoAndroid&) = delete;
+  CastSysInfoAndroid& operator=(const CastSysInfoAndroid&) = delete;
+
   ~CastSysInfoAndroid() override;
 
   // CastSysInfo implementation:
@@ -45,8 +49,6 @@
 
  private:
   const base::android::BuildInfo* const build_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastSysInfoAndroid);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/cast_sys_info_dummy.h b/chromecast/base/cast_sys_info_dummy.h
index 332a5f3..51932faf 100644
--- a/chromecast/base/cast_sys_info_dummy.h
+++ b/chromecast/base/cast_sys_info_dummy.h
@@ -19,6 +19,10 @@
  public:
   CastSysInfoDummy();
   CastSysInfoDummy(const std::string& sys_info_file);
+
+  CastSysInfoDummy(const CastSysInfoDummy&) = delete;
+  CastSysInfoDummy& operator=(const CastSysInfoDummy&) = delete;
+
   ~CastSysInfoDummy() override;
 
   // CastSysInfo implementation:
@@ -69,8 +73,6 @@
   std::string wifi_interface_;
   std::string ap_interface_;
   std::string ssid_suffix_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastSysInfoDummy);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/chromecast_config_android_dummy.cc b/chromecast/base/chromecast_config_android_dummy.cc
index 33494c34..726b2d02 100644
--- a/chromecast/base/chromecast_config_android_dummy.cc
+++ b/chromecast/base/chromecast_config_android_dummy.cc
@@ -14,6 +14,10 @@
  public:
   ChromecastConfigAndroidDummy() {}
 
+  ChromecastConfigAndroidDummy(const ChromecastConfigAndroidDummy&) = delete;
+  ChromecastConfigAndroidDummy& operator=(const ChromecastConfigAndroidDummy&) =
+      delete;
+
   ~ChromecastConfigAndroidDummy() override {}
 
   bool CanSendUsageStats() override { return false; }
@@ -27,8 +31,6 @@
 
  private:
   friend class base::NoDestructor<ChromecastConfigAndroidDummy>;
-
-  DISALLOW_COPY_AND_ASSIGN(ChromecastConfigAndroidDummy);
 };
 
 // static
diff --git a/chromecast/base/component/component_internal.h b/chromecast/base/component/component_internal.h
index d3a37fa..6460066 100644
--- a/chromecast/base/component/component_internal.h
+++ b/chromecast/base/component/component_internal.h
@@ -33,6 +33,10 @@
 class DependencyBase {
  public:
   DependencyBase(const WeakReferenceBase& dependency, ComponentBase* dependent);
+
+  DependencyBase(const DependencyBase&) = delete;
+  DependencyBase& operator=(const DependencyBase&) = delete;
+
   ~DependencyBase();
 
   void StartUsing();
@@ -52,8 +56,6 @@
 
   const scoped_refptr<DependencyCount> counter_;
   base::ThreadChecker thread_checker_;
-
-  DISALLOW_COPY_AND_ASSIGN(DependencyBase);
 };
 
 // Base class for weak dependencies. Weak dependencies cannot be used
diff --git a/chromecast/base/device_capabilities_impl.h b/chromecast/base/device_capabilities_impl.h
index f24427c..a085cf60 100644
--- a/chromecast/base/device_capabilities_impl.h
+++ b/chromecast/base/device_capabilities_impl.h
@@ -23,6 +23,9 @@
 
 class DeviceCapabilitiesImpl : public DeviceCapabilities {
  public:
+  DeviceCapabilitiesImpl(const DeviceCapabilitiesImpl&) = delete;
+  DeviceCapabilitiesImpl& operator=(const DeviceCapabilitiesImpl&) = delete;
+
   ~DeviceCapabilitiesImpl() override;
 
   // DeviceCapabilities implementation:
@@ -46,6 +49,10 @@
   class ValidatorInfo : public base::SupportsWeakPtr<ValidatorInfo> {
    public:
     explicit ValidatorInfo(Validator* validator);
+
+    ValidatorInfo(const ValidatorInfo&) = delete;
+    ValidatorInfo& operator=(const ValidatorInfo&) = delete;
+
     ~ValidatorInfo();
 
     Validator* validator() const { return validator_; }
@@ -60,8 +67,6 @@
     Validator* const validator_;
     // TaskRunner of thread that validator_ was registered on
     const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
-    DISALLOW_COPY_AND_ASSIGN(ValidatorInfo);
   };
 
   // For DeviceCapabilitiesImpl()
@@ -104,8 +109,6 @@
 
   ValidatorMap validator_map_;
   const scoped_refptr<base::ObserverListThreadSafe<Observer>> observer_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeviceCapabilitiesImpl);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/device_capabilities_impl_unittest.cc b/chromecast/base/device_capabilities_impl_unittest.cc
index 33d01a8..a547450 100644
--- a/chromecast/base/device_capabilities_impl_unittest.cc
+++ b/chromecast/base/device_capabilities_impl_unittest.cc
@@ -138,12 +138,13 @@
 class MockCapabilitiesObserver : public DeviceCapabilities::Observer {
  public:
   MockCapabilitiesObserver() {}
+
+  MockCapabilitiesObserver(const MockCapabilitiesObserver&) = delete;
+  MockCapabilitiesObserver& operator=(const MockCapabilitiesObserver&) = delete;
+
   ~MockCapabilitiesObserver() override {}
 
   MOCK_METHOD1(OnCapabilitiesChanged, void(const std::string& path));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockCapabilitiesObserver);
 };
 
 // Test fixtures needs an example default capability to test DeviceCapabilities
diff --git a/chromecast/base/metrics/grouped_histogram.cc b/chromecast/base/metrics/grouped_histogram.cc
index 51cbbc7..f654eab 100644
--- a/chromecast/base/metrics/grouped_histogram.cc
+++ b/chromecast/base/metrics/grouped_histogram.cc
@@ -99,6 +99,9 @@
         maximum_(maximum),
         bucket_count_(ranges->bucket_count()) {}
 
+  GroupedHistogram(const GroupedHistogram&) = delete;
+  GroupedHistogram& operator=(const GroupedHistogram&) = delete;
+
   ~GroupedHistogram() override {
   }
 
@@ -127,8 +130,6 @@
   Sample minimum_;
   Sample maximum_;
   uint32_t bucket_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(GroupedHistogram);
 };
 
 // Registers a GroupedHistogram with StatisticsRecorder.  Must be called
diff --git a/chromecast/base/metrics/mock_cast_metrics_helper.h b/chromecast/base/metrics/mock_cast_metrics_helper.h
index 9afd107..57c03759 100644
--- a/chromecast/base/metrics/mock_cast_metrics_helper.h
+++ b/chromecast/base/metrics/mock_cast_metrics_helper.h
@@ -17,6 +17,10 @@
 class MockCastMetricsHelper : public CastMetricsHelper {
  public:
   MockCastMetricsHelper();
+
+  MockCastMetricsHelper(const MockCastMetricsHelper&) = delete;
+  MockCastMetricsHelper& operator=(const MockCastMetricsHelper&) = delete;
+
   ~MockCastMetricsHelper() override;
 
   MOCK_METHOD2(UpdateCurrentAppInfo,
@@ -39,9 +43,6 @@
                                  const std::string& suffix));
   MOCK_METHOD1(SetMetricsSink, void(MetricsSink* delegate));
   MOCK_METHOD1(SetRecordActionCallback, void(RecordActionCallback callback));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockCastMetricsHelper);
 };
 
 }  // namespace metrics
diff --git a/chromecast/base/observer_unittest.cc b/chromecast/base/observer_unittest.cc
index 412a651..e317d876 100644
--- a/chromecast/base/observer_unittest.cc
+++ b/chromecast/base/observer_unittest.cc
@@ -64,6 +64,9 @@
     thread_.Start();
   }
 
+  ThreadedObserver(const ThreadedObserver&) = delete;
+  ThreadedObserver& operator=(const ThreadedObserver&) = delete;
+
   ~ThreadedObserver() {
     thread_.task_runner()->PostTask(
         FROM_HERE, base::BindOnce(&ThreadedObserver::DestroyOnThread,
@@ -104,8 +107,6 @@
   base::Thread thread_;
   std::unique_ptr<Observer<int>> observer_;
   base::WaitableEvent observing_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadedObserver);
 };
 
 void RunCallback(std::function<void()> callback) {
diff --git a/chromecast/base/scoped_temp_file.h b/chromecast/base/scoped_temp_file.h
index 57703e59..60663995 100644
--- a/chromecast/base/scoped_temp_file.h
+++ b/chromecast/base/scoped_temp_file.h
@@ -18,6 +18,10 @@
 class ScopedTempFile {
  public:
   ScopedTempFile();
+
+  ScopedTempFile(const ScopedTempFile&) = delete;
+  ScopedTempFile& operator=(const ScopedTempFile&) = delete;
+
   ~ScopedTempFile();
 
   // Return the path to the temporary file. Note that if the underlying file has
@@ -38,8 +42,6 @@
 
  private:
   base::FilePath path_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedTempFile);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/statistics/weighted_moving_average.h b/chromecast/base/statistics/weighted_moving_average.h
index 6965714..70c4989 100644
--- a/chromecast/base/statistics/weighted_moving_average.h
+++ b/chromecast/base/statistics/weighted_moving_average.h
@@ -24,6 +24,10 @@
 class WeightedMovingAverage {
  public:
   explicit WeightedMovingAverage(int64_t max_x_range);
+
+  WeightedMovingAverage(const WeightedMovingAverage&) = delete;
+  WeightedMovingAverage& operator=(const WeightedMovingAverage&) = delete;
+
   ~WeightedMovingAverage();
 
   int64_t max_x_range() const { return max_x_range_; }
@@ -52,8 +56,6 @@
   const int64_t max_x_range_;
   std::deque<Sample> samples_;
   WeightedMean mean_;
-
-  DISALLOW_COPY_AND_ASSIGN(WeightedMovingAverage);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/statistics/weighted_moving_linear_regression.h b/chromecast/base/statistics/weighted_moving_linear_regression.h
index d03fb6f..339bd85 100644
--- a/chromecast/base/statistics/weighted_moving_linear_regression.h
+++ b/chromecast/base/statistics/weighted_moving_linear_regression.h
@@ -31,6 +31,12 @@
   };
 
   explicit WeightedMovingLinearRegression(int64_t max_x_range);
+
+  WeightedMovingLinearRegression(const WeightedMovingLinearRegression&) =
+      delete;
+  WeightedMovingLinearRegression& operator=(
+      const WeightedMovingLinearRegression&) = delete;
+
   ~WeightedMovingLinearRegression();
 
   // Returns the current number of samples that are in the regression.
@@ -81,8 +87,6 @@
   double intercept_variance_ = 0.0;
 
   bool has_estimate_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(WeightedMovingLinearRegression);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/system_time_change_notifier.h b/chromecast/base/system_time_change_notifier.h
index 469d245c..d4cad93e 100644
--- a/chromecast/base/system_time_change_notifier.h
+++ b/chromecast/base/system_time_change_notifier.h
@@ -58,6 +58,12 @@
  public:
   explicit SystemTimeChangeNotifierPeriodicMonitor(
       const scoped_refptr<base::SequencedTaskRunner>& task_runner);
+
+  SystemTimeChangeNotifierPeriodicMonitor(
+      const SystemTimeChangeNotifierPeriodicMonitor&) = delete;
+  SystemTimeChangeNotifierPeriodicMonitor& operator=(
+      const SystemTimeChangeNotifierPeriodicMonitor&) = delete;
+
   ~SystemTimeChangeNotifierPeriodicMonitor() override;
 
   // For unittests.
@@ -81,8 +87,6 @@
   base::Time fake_now_;
 
   base::WeakPtrFactory<SystemTimeChangeNotifierPeriodicMonitor> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(SystemTimeChangeNotifierPeriodicMonitor);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/system_time_change_notifier_unittest.cc b/chromecast/base/system_time_change_notifier_unittest.cc
index 8f55085b..55a6dcb 100644
--- a/chromecast/base/system_time_change_notifier_unittest.cc
+++ b/chromecast/base/system_time_change_notifier_unittest.cc
@@ -51,6 +51,10 @@
 class TimeChangeObserver : public SystemTimeChangeNotifier::Observer {
  public:
   TimeChangeObserver() : num_time_changed_(0) {}
+
+  TimeChangeObserver(const TimeChangeObserver&) = delete;
+  TimeChangeObserver& operator=(const TimeChangeObserver&) = delete;
+
   ~TimeChangeObserver() override {}
 
   // SystemTimeChangeNotifier::Observer implementation:
@@ -60,8 +64,6 @@
 
  private:
   int num_time_changed_;
-
-  DISALLOW_COPY_AND_ASSIGN(TimeChangeObserver);
 };
 
 }  // namespace
diff --git a/chromecast/base/task_runner_impl.h b/chromecast/base/task_runner_impl.h
index 4b4cbe49..9a02fb7 100644
--- a/chromecast/base/task_runner_impl.h
+++ b/chromecast/base/task_runner_impl.h
@@ -23,6 +23,10 @@
  public:
   TaskRunnerImpl();
   explicit TaskRunnerImpl(scoped_refptr<base::SingleThreadTaskRunner> runner);
+
+  TaskRunnerImpl(const TaskRunnerImpl&) = delete;
+  TaskRunnerImpl& operator=(const TaskRunnerImpl&) = delete;
+
   ~TaskRunnerImpl() override;
 
   bool PostTask(Task* task, uint64_t delay_milliseconds) override;
@@ -33,8 +37,6 @@
 
  private:
   const scoped_refptr<base::SingleThreadTaskRunner> runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(TaskRunnerImpl);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/base/thread_health_checker.h b/chromecast/base/thread_health_checker.h
index e0c0495..be71ae1 100644
--- a/chromecast/base/thread_health_checker.h
+++ b/chromecast/base/thread_health_checker.h
@@ -39,6 +39,10 @@
       base::TimeDelta interval,
       base::TimeDelta timeout,
       base::RepeatingClosure on_failure);
+
+  ThreadHealthChecker(const ThreadHealthChecker&) = delete;
+  ThreadHealthChecker& operator=(const ThreadHealthChecker&) = delete;
+
   ~ThreadHealthChecker();
 
  private:
@@ -72,8 +76,6 @@
 
   scoped_refptr<base::SequencedTaskRunner> doctor_task_runner_;
   scoped_refptr<Internal> internal_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThreadHealthChecker);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/bindings/bindings_manager_cast_browsertest.cc b/chromecast/bindings/bindings_manager_cast_browsertest.cc
index e44fad8..7c17097f 100644
--- a/chromecast/bindings/bindings_manager_cast_browsertest.cc
+++ b/chromecast/bindings/bindings_manager_cast_browsertest.cc
@@ -67,6 +67,10 @@
 class TitleChangeObserver : public CastWebContentsObserver {
  public:
   TitleChangeObserver() = default;
+
+  TitleChangeObserver(const TitleChangeObserver&) = delete;
+  TitleChangeObserver& operator=(const TitleChangeObserver&) = delete;
+
   ~TitleChangeObserver() override = default;
 
   // Spins a Runloop until the title of the page matches the |expected_title|
@@ -97,8 +101,6 @@
   std::string expected_title_;
 
   base::OnceClosure quit_closure_;
-
-  DISALLOW_COPY_AND_ASSIGN(TitleChangeObserver);
 };
 
 // =============================================================================
@@ -107,12 +109,13 @@
 class MockWebContentsDelegate : public content::WebContentsDelegate {
  public:
   MockWebContentsDelegate() = default;
+
+  MockWebContentsDelegate(const MockWebContentsDelegate&) = delete;
+  MockWebContentsDelegate& operator=(const MockWebContentsDelegate&) = delete;
+
   ~MockWebContentsDelegate() override = default;
 
   MOCK_METHOD1(CloseContents, void(content::WebContents* source));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockWebContentsDelegate);
 };
 
 }  // namespace
diff --git a/chromecast/bindings/bindings_manager_fuchsia.h b/chromecast/bindings/bindings_manager_fuchsia.h
index 0f90e3d6..5bae06e 100644
--- a/chromecast/bindings/bindings_manager_fuchsia.h
+++ b/chromecast/bindings/bindings_manager_fuchsia.h
@@ -20,6 +20,10 @@
                                public BindingsManager {
  public:
   BindingsManagerFuchsia();
+
+  BindingsManagerFuchsia(const BindingsManagerFuchsia&) = delete;
+  BindingsManagerFuchsia& operator=(const BindingsManagerFuchsia&) = delete;
+
   ~BindingsManagerFuchsia() override;
 
   // BindingsManager implementation:
@@ -37,8 +41,6 @@
   // Stores all bindings, keyed on the string-based IDs provided by the
   // ApiBindings interface.
   std::map<std::string, fuchsia::mem::Buffer> bindings_;
-
-  DISALLOW_COPY_AND_ASSIGN(BindingsManagerFuchsia);
 };
 
 }  // namespace bindings
diff --git a/chromecast/browser/accessibility/touch_exploration_controller.h b/chromecast/browser/accessibility/touch_exploration_controller.h
index 2bb9750..3cf3dcb 100644
--- a/chromecast/browser/accessibility/touch_exploration_controller.h
+++ b/chromecast/browser/accessibility/touch_exploration_controller.h
@@ -174,6 +174,11 @@
       aura::Window* root_window,
       TouchExplorationControllerDelegate* delegate,
       AccessibilitySoundPlayer* accessibility_sound_player);
+
+  TouchExplorationController(const TouchExplorationController&) = delete;
+  TouchExplorationController& operator=(const TouchExplorationController&) =
+      delete;
+
   ~TouchExplorationController() override;
 
   // Make synthesized touch events are anchored at this point. This is
@@ -509,8 +514,6 @@
   // Whether or not to trigger pass through mode when touch events come
   // in from the edges.
   bool side_gesture_pass_through_;
-
-  DISALLOW_COPY_AND_ASSIGN(TouchExplorationController);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc b/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc
index 617ff63..17d90db 100644
--- a/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc
+++ b/chromecast/browser/accessibility/touch_exploration_controller_unittest.cc
@@ -40,6 +40,10 @@
 class EventCapturer : public ui::EventHandler {
  public:
   EventCapturer() {}
+
+  EventCapturer(const EventCapturer&) = delete;
+  EventCapturer& operator=(const EventCapturer&) = delete;
+
   ~EventCapturer() override {}
 
   void Reset() { events_.clear(); }
@@ -63,8 +67,6 @@
 
  private:
   EventList events_;
-
-  DISALLOW_COPY_AND_ASSIGN(EventCapturer);
 };
 
 int Factorial(int n) {
@@ -227,6 +229,10 @@
 class TouchExplorationTest : public aura::test::AuraTestBase {
  public:
   TouchExplorationTest() {}
+
+  TouchExplorationTest(const TouchExplorationTest&) = delete;
+  TouchExplorationTest& operator=(const TouchExplorationTest&) = delete;
+
   ~TouchExplorationTest() override {}
 
   void SetUp() override {
@@ -417,8 +423,6 @@
   std::unique_ptr<TouchExplorationControllerTestApi>
       touch_exploration_controller_;
   std::unique_ptr<aura::test::TestCursorClient> cursor_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest);
 };
 
 // Executes a number of assertions to confirm that |e1| and |e2| are touch
diff --git a/chromecast/browser/accessibility/touch_exploration_manager.h b/chromecast/browser/accessibility/touch_exploration_manager.h
index 93bb20d2..ae9071c 100644
--- a/chromecast/browser/accessibility/touch_exploration_manager.h
+++ b/chromecast/browser/accessibility/touch_exploration_manager.h
@@ -36,6 +36,10 @@
       AccessibilityFocusRingController* accessibility_focus_ring_controller,
       AccessibilitySoundPlayer* accessibility_sound_player,
       CastGestureHandler* cast_gesture_handler);
+
+  TouchExplorationManager(const TouchExplorationManager&) = delete;
+  TouchExplorationManager& operator=(const TouchExplorationManager&) = delete;
+
   ~TouchExplorationManager() override;
 
   // Enable or disable touch exploration.
@@ -78,8 +82,6 @@
   AccessibilityFocusRingController* accessibility_focus_ring_controller_;
   AccessibilitySoundPlayer* accessibility_sound_player_;
   CastGestureHandler* cast_gesture_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(TouchExplorationManager);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/android/cast_content_window_android.h b/chromecast/browser/android/cast_content_window_android.h
index 534cdec..15353e5 100644
--- a/chromecast/browser/android/cast_content_window_android.h
+++ b/chromecast/browser/android/cast_content_window_android.h
@@ -23,6 +23,10 @@
  public:
   CastContentWindowAndroid(base::WeakPtr<Delegate> delegate,
                            mojom::CastWebViewParamsPtr params);
+
+  CastContentWindowAndroid(const CastContentWindowAndroid&) = delete;
+  CastContentWindowAndroid& operator=(const CastContentWindowAndroid&) = delete;
+
   ~CastContentWindowAndroid() override;
 
   // CastContentWindow implementation:
@@ -52,8 +56,6 @@
  private:
   bool web_contents_attached_;
   base::android::ScopedJavaGlobalRef<jobject> java_window_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastContentWindowAndroid);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/application_media_capabilities.h b/chromecast/browser/application_media_capabilities.h
index 735f4c05..ab2d736 100644
--- a/chromecast/browser/application_media_capabilities.h
+++ b/chromecast/browser/application_media_capabilities.h
@@ -22,6 +22,11 @@
     : public mojom::ApplicationMediaCapabilities {
  public:
   ApplicationMediaCapabilities();
+
+  ApplicationMediaCapabilities(const ApplicationMediaCapabilities&) = delete;
+  ApplicationMediaCapabilities& operator=(const ApplicationMediaCapabilities&) =
+      delete;
+
   ~ApplicationMediaCapabilities() override;
 
   void AddReceiver(
@@ -38,8 +43,6 @@
   mojo::ReceiverSet<mojom::ApplicationMediaCapabilities> receivers_;
   mojo::RemoteSet<mojom::ApplicationMediaCapabilitiesObserver> observers_;
   BitstreamAudioCodecsInfo supported_bitstream_audio_codecs_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(ApplicationMediaCapabilities);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/application_media_info_manager.h b/chromecast/browser/application_media_info_manager.h
index 6000e29..04899ebc 100644
--- a/chromecast/browser/application_media_info_manager.h
+++ b/chromecast/browser/application_media_info_manager.h
@@ -34,6 +34,11 @@
           receiver,
       std::string application_session_id,
       bool mixer_audio_enabled);
+
+  ApplicationMediaInfoManager(const ApplicationMediaInfoManager&) = delete;
+  ApplicationMediaInfoManager& operator=(const ApplicationMediaInfoManager&) =
+      delete;
+
   ~ApplicationMediaInfoManager() override;
 
   void SetRendererBlock(bool renderer_blocked);
@@ -49,8 +54,6 @@
   bool mixer_audio_enabled_;
   // Flag to determine if renderer can start.
   bool renderer_blocked_;
-
-  DISALLOW_COPY_AND_ASSIGN(ApplicationMediaInfoManager);
 };
 
 void CreateApplicationMediaInfoManager(
diff --git a/chromecast/browser/bluetooth/cast_bluetooth_chooser.h b/chromecast/browser/bluetooth/cast_bluetooth_chooser.h
index 6841653..cca3956 100644
--- a/chromecast/browser/bluetooth/cast_bluetooth_chooser.h
+++ b/chromecast/browser/bluetooth/cast_bluetooth_chooser.h
@@ -29,6 +29,10 @@
   CastBluetoothChooser(content::BluetoothChooser::EventHandler event_handler,
                        mojo::PendingRemote<mojom::BluetoothDeviceAccessProvider>
                            pending_provider);
+
+  CastBluetoothChooser(const CastBluetoothChooser&) = delete;
+  CastBluetoothChooser& operator=(const CastBluetoothChooser&) = delete;
+
   ~CastBluetoothChooser() override;
 
  private:
@@ -57,8 +61,6 @@
   std::unordered_set<std::string> available_devices_;
   std::unordered_set<std::string> approved_devices_;
   bool all_devices_approved_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(CastBluetoothChooser);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc b/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc
index 61a2aca..2e9b23d 100644
--- a/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc
+++ b/chromecast/browser/bluetooth/cast_bluetooth_chooser_unittest.cc
@@ -16,6 +16,11 @@
 class SimpleDeviceAccessProvider : public mojom::BluetoothDeviceAccessProvider {
  public:
   SimpleDeviceAccessProvider() = default;
+
+  SimpleDeviceAccessProvider(const SimpleDeviceAccessProvider&) = delete;
+  SimpleDeviceAccessProvider& operator=(const SimpleDeviceAccessProvider&) =
+      delete;
+
   ~SimpleDeviceAccessProvider() override = default;
 
   // mojom::BluetoothDeviceAccessProvider implementation:
@@ -42,8 +47,6 @@
   mojo::Remote<mojom::BluetoothDeviceAccessProviderClient> client_;
   base::MockCallback<base::OnceClosure> connection_closed_;
   std::vector<std::string> approved_devices_;
-
-  DISALLOW_COPY_AND_ASSIGN(SimpleDeviceAccessProvider);
 };
 
 }  // namespace
@@ -58,6 +61,9 @@
     task_environment_.RunUntilIdle();
   }
 
+  CastBluetoothChooserTest(const CastBluetoothChooserTest&) = delete;
+  CastBluetoothChooserTest& operator=(const CastBluetoothChooserTest&) = delete;
+
   ~CastBluetoothChooserTest() override = default;
 
   void AddDeviceToChooser(const std::string& address) {
@@ -76,8 +82,6 @@
   SimpleDeviceAccessProvider provider_;
   mojo::Receiver<mojom::BluetoothDeviceAccessProvider> provider_receiver_;
   std::unique_ptr<CastBluetoothChooser> cast_bluetooth_chooser_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastBluetoothChooserTest);
 };
 
 TEST_F(CastBluetoothChooserTest, GrantAccessBeforeDeviceAvailable) {
diff --git a/chromecast/browser/cast_browser_context.cc b/chromecast/browser/cast_browser_context.cc
index 0922c1f0..decbe66 100644
--- a/chromecast/browser/cast_browser_context.cc
+++ b/chromecast/browser/cast_browser_context.cc
@@ -34,10 +34,11 @@
     : public content::ResourceContext {
  public:
   CastResourceContext() {}
-  ~CastResourceContext() override {}
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastResourceContext);
+  CastResourceContext(const CastResourceContext&) = delete;
+  CastResourceContext& operator=(const CastResourceContext&) = delete;
+
+  ~CastResourceContext() override {}
 };
 
 CastBrowserContext::CastBrowserContext()
diff --git a/chromecast/browser/cast_browser_context.h b/chromecast/browser/cast_browser_context.h
index 492d941..389c7f2 100644
--- a/chromecast/browser/cast_browser_context.h
+++ b/chromecast/browser/cast_browser_context.h
@@ -22,6 +22,10 @@
 class CastBrowserContext final : public content::BrowserContext {
  public:
   CastBrowserContext();
+
+  CastBrowserContext(const CastBrowserContext&) = delete;
+  CastBrowserContext& operator=(const CastBrowserContext&) = delete;
+
   ~CastBrowserContext() override;
 
   // BrowserContext implementation:
@@ -60,8 +64,6 @@
   std::unique_ptr<CastResourceContext> resource_context_;
   std::unique_ptr<content::PermissionControllerDelegate> permission_manager_;
   std::unique_ptr<SimpleFactoryKey> simple_factory_key_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastBrowserContext);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_browser_main_parts.cc b/chromecast/browser/cast_browser_main_parts.cc
index ff1e2e1e..3a1ecbe 100644
--- a/chromecast/browser/cast_browser_main_parts.cc
+++ b/chromecast/browser/cast_browser_main_parts.cc
@@ -267,10 +267,11 @@
 class CastViewsDelegate : public views::ViewsDelegate {
  public:
   CastViewsDelegate() = default;
-  ~CastViewsDelegate() override = default;
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastViewsDelegate);
+  CastViewsDelegate(const CastViewsDelegate&) = delete;
+  CastViewsDelegate& operator=(const CastViewsDelegate&) = delete;
+
+  ~CastViewsDelegate() override = default;
 };
 
 #endif  // defined(USE_AURA)
diff --git a/chromecast/browser/cast_browser_main_parts.h b/chromecast/browser/cast_browser_main_parts.h
index b3df053..feab52c6 100644
--- a/chromecast/browser/cast_browser_main_parts.h
+++ b/chromecast/browser/cast_browser_main_parts.h
@@ -77,6 +77,10 @@
   // This class does not take ownership of |url_request_content_factory|.
   CastBrowserMainParts(const content::MainFunctionParams& parameters,
                        CastContentBrowserClient* cast_content_browser_client);
+
+  CastBrowserMainParts(const CastBrowserMainParts&) = delete;
+  CastBrowserMainParts& operator=(const CastBrowserMainParts&) = delete;
+
   ~CastBrowserMainParts() override;
 
   media::MediaPipelineBackendManager* media_pipeline_backend_manager();
@@ -152,8 +156,6 @@
 #endif  // defined(USE_AURA) && !defined(OS_FUCHSIA)
 
   bool run_message_loop_ = true;
-
-  DISALLOW_COPY_AND_ASSIGN(CastBrowserMainParts);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_browser_process.h b/chromecast/browser/cast_browser_process.h
index 2c3e562..132d844 100644
--- a/chromecast/browser/cast_browser_process.h
+++ b/chromecast/browser/cast_browser_process.h
@@ -43,6 +43,10 @@
   static CastBrowserProcess* GetInstance();
 
   CastBrowserProcess();
+
+  CastBrowserProcess(const CastBrowserProcess&) = delete;
+  CastBrowserProcess& operator=(const CastBrowserProcess&) = delete;
+
   virtual ~CastBrowserProcess();
 
   void SetBrowserContext(std::unique_ptr<CastBrowserContext> browser_context);
@@ -125,8 +129,6 @@
 
   // Note: CastService must be destroyed before others.
   std::unique_ptr<CastService> cast_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastBrowserProcess);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_content_browser_client.h b/chromecast/browser/cast_content_browser_client.h
index 0f85eaa5..a6cb792 100644
--- a/chromecast/browser/cast_content_browser_client.h
+++ b/chromecast/browser/cast_content_browser_client.h
@@ -98,6 +98,9 @@
   // preflight checks.
   static std::vector<std::string> GetCorsExemptHeadersList();
 
+  CastContentBrowserClient(const CastContentBrowserClient&) = delete;
+  CastContentBrowserClient& operator=(const CastContentBrowserClient&) = delete;
+
   ~CastContentBrowserClient() override;
 
   // Generally we discourage Initialize methods. Unfortunately, we can't do
@@ -386,8 +389,6 @@
   std::unique_ptr<external_service_support::ExternalConnector> media_connector_;
 
   CastFeatureListCreator* cast_feature_list_creator_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastContentBrowserClient);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_content_window_aura.cc b/chromecast/browser/cast_content_window_aura.cc
index e359a259..f69bef18d 100644
--- a/chromecast/browser/cast_content_window_aura.cc
+++ b/chromecast/browser/cast_content_window_aura.cc
@@ -46,6 +46,9 @@
     }
   }
 
+  TouchBlocker(const TouchBlocker&) = delete;
+  TouchBlocker& operator=(const TouchBlocker&) = delete;
+
   ~TouchBlocker() override {
     if (window_) {
       window_->RemoveObserver(this);
@@ -82,8 +85,6 @@
 
   aura::Window* window_;
   bool activated_;
-
-  DISALLOW_COPY_AND_ASSIGN(TouchBlocker);
 };
 
 CastContentWindowAura::CastContentWindowAura(base::WeakPtr<Delegate> delegate,
diff --git a/chromecast/browser/cast_content_window_aura.h b/chromecast/browser/cast_content_window_aura.h
index 44509146..882be67 100644
--- a/chromecast/browser/cast_content_window_aura.h
+++ b/chromecast/browser/cast_content_window_aura.h
@@ -31,6 +31,10 @@
   CastContentWindowAura(base::WeakPtr<Delegate> delegate,
                         mojom::CastWebViewParamsPtr params,
                         CastWindowManager* window_manager);
+
+  CastContentWindowAura(const CastContentWindowAura&) = delete;
+  CastContentWindowAura& operator=(const CastContentWindowAura&) = delete;
+
   ~CastContentWindowAura() override;
 
   // CastContentWindow implementation:
@@ -69,8 +73,6 @@
   aura::Window* window_;
   bool has_screen_access_;
   bool resize_window_when_navigation_starts_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastContentWindowAura);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/cast_display_configurator.h b/chromecast/browser/cast_display_configurator.h
index 2c31c9c..3e05211a 100644
--- a/chromecast/browser/cast_display_configurator.h
+++ b/chromecast/browser/cast_display_configurator.h
@@ -47,6 +47,10 @@
   };
 
   explicit CastDisplayConfigurator(CastScreen* screen);
+
+  CastDisplayConfigurator(const CastDisplayConfigurator&) = delete;
+  CastDisplayConfigurator& operator=(const CastDisplayConfigurator&) = delete;
+
   ~CastDisplayConfigurator() override;
 
   // display::NativeDisplayObserver implementation
@@ -88,8 +92,6 @@
   CastScreen* const cast_screen_;
 
   base::WeakPtrFactory<CastDisplayConfigurator> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastDisplayConfigurator);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_download_manager_delegate.h b/chromecast/browser/cast_download_manager_delegate.h
index 37fda98..8eecdb2 100644
--- a/chromecast/browser/cast_download_manager_delegate.h
+++ b/chromecast/browser/cast_download_manager_delegate.h
@@ -16,6 +16,11 @@
                                     public base::SupportsUserData::Data {
  public:
   CastDownloadManagerDelegate();
+
+  CastDownloadManagerDelegate(const CastDownloadManagerDelegate&) = delete;
+  CastDownloadManagerDelegate& operator=(const CastDownloadManagerDelegate&) =
+      delete;
+
   ~CastDownloadManagerDelegate() override;
 
   // content::DownloadManagerDelegate implementation:
@@ -28,9 +33,6 @@
   bool ShouldOpenDownload(
       download::DownloadItem* item,
       content::DownloadOpenDelayedCallback callback) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastDownloadManagerDelegate);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_http_user_agent_settings.h b/chromecast/browser/cast_http_user_agent_settings.h
index 47885941..51516024 100644
--- a/chromecast/browser/cast_http_user_agent_settings.h
+++ b/chromecast/browser/cast_http_user_agent_settings.h
@@ -17,6 +17,11 @@
 class CastHttpUserAgentSettings : public net::HttpUserAgentSettings {
  public:
   CastHttpUserAgentSettings();
+
+  CastHttpUserAgentSettings(const CastHttpUserAgentSettings&) = delete;
+  CastHttpUserAgentSettings& operator=(const CastHttpUserAgentSettings&) =
+      delete;
+
   ~CastHttpUserAgentSettings() override;
 
   // net::HttpUserAgentSettings implementation:
@@ -30,8 +35,6 @@
  private:
   mutable std::string last_locale_;
   mutable std::string accept_language_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastHttpUserAgentSettings);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_media_blocker_unittest.cc b/chromecast/browser/cast_media_blocker_unittest.cc
index 47e6fc9..a6553ae 100644
--- a/chromecast/browser/cast_media_blocker_unittest.cc
+++ b/chromecast/browser/cast_media_blocker_unittest.cc
@@ -27,6 +27,10 @@
 class MockMediaSession : public content::MediaSession {
  public:
   MockMediaSession() {}
+
+  MockMediaSession(const MockMediaSession&) = delete;
+  MockMediaSession& operator=(const MockMediaSession&) = delete;
+
   ~MockMediaSession() override {}
 
   MOCK_METHOD1(Resume, void(content::MediaSession::SuspendType));
@@ -62,9 +66,6 @@
   MOCK_METHOD0(HangUp, void());
   MOCK_METHOD0(Raise, void());
   MOCK_METHOD1(SetMute, void(bool));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockMediaSession);
 };
 
 }  // namespace
@@ -72,6 +73,10 @@
 class CastMediaBlockerTest : public content::RenderViewHostTestHarness {
  public:
   CastMediaBlockerTest() {}
+
+  CastMediaBlockerTest(const CastMediaBlockerTest&) = delete;
+  CastMediaBlockerTest& operator=(const CastMediaBlockerTest&) = delete;
+
   ~CastMediaBlockerTest() override {}
 
   void SetUp() override {
@@ -106,9 +111,6 @@
   std::unique_ptr<MockMediaSession> media_session_;
   std::unique_ptr<CastMediaBlocker> media_blocker_;
   std::unique_ptr<content::WebContents> web_contents_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastMediaBlockerTest);
 };
 
 TEST_F(CastMediaBlockerTest, Block_Unblock_Suspended) {
diff --git a/chromecast/browser/cast_network_contexts.h b/chromecast/browser/cast_network_contexts.h
index d3deba20..5c44aa9 100644
--- a/chromecast/browser/cast_network_contexts.h
+++ b/chromecast/browser/cast_network_contexts.h
@@ -53,6 +53,10 @@
  public:
   explicit CastNetworkContexts(
       std::vector<std::string> cors_exempt_headers_list);
+
+  CastNetworkContexts(const CastNetworkContexts&) = delete;
+  CastNetworkContexts& operator=(const CastNetworkContexts&) = delete;
+
   ~CastNetworkContexts() override;
 
   // Returns the System NetworkContext. Does any initialization of the
@@ -142,8 +146,6 @@
   mojo::ReceiverSet<network::mojom::ProxyConfigPollerClient>
       poller_receiver_set_;
   mojo::RemoteSet<network::mojom::ProxyConfigClient> proxy_config_client_set_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastNetworkContexts);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_permission_manager.h b/chromecast/browser/cast_permission_manager.h
index bfac0b21..548c81b6 100644
--- a/chromecast/browser/cast_permission_manager.h
+++ b/chromecast/browser/cast_permission_manager.h
@@ -16,6 +16,10 @@
 class CastPermissionManager : public content::PermissionControllerDelegate {
  public:
   CastPermissionManager();
+
+  CastPermissionManager(const CastPermissionManager&) = delete;
+  CastPermissionManager& operator=(const CastPermissionManager&) = delete;
+
   ~CastPermissionManager() override;
 
   // content::PermissionControllerDelegate implementation:
@@ -53,9 +57,6 @@
       override;
   void UnsubscribePermissionStatusChange(
       SubscriptionId subscription_id) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastPermissionManager);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_resource_bundle_unittest.cc b/chromecast/browser/cast_resource_bundle_unittest.cc
index fd42005b..28b3684 100644
--- a/chromecast/browser/cast_resource_bundle_unittest.cc
+++ b/chromecast/browser/cast_resource_bundle_unittest.cc
@@ -17,10 +17,11 @@
 class CastResourceBundleTest : public testing::Test {
  public:
   CastResourceBundleTest() {}
-  ~CastResourceBundleTest() override {}
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastResourceBundleTest);
+  CastResourceBundleTest(const CastResourceBundleTest&) = delete;
+  CastResourceBundleTest& operator=(const CastResourceBundleTest&) = delete;
+
+  ~CastResourceBundleTest() override {}
 };
 
 TEST_F(CastResourceBundleTest, DelegateLoadLocalizedResourceBytes) {
diff --git a/chromecast/browser/cast_system_memory_pressure_evaluator.h b/chromecast/browser/cast_system_memory_pressure_evaluator.h
index 273f400..9f8f0e3 100644
--- a/chromecast/browser/cast_system_memory_pressure_evaluator.h
+++ b/chromecast/browser/cast_system_memory_pressure_evaluator.h
@@ -28,6 +28,12 @@
  public:
   explicit CastSystemMemoryPressureEvaluator(
       std::unique_ptr<memory_pressure::MemoryPressureVoter> voter);
+
+  CastSystemMemoryPressureEvaluator(const CastSystemMemoryPressureEvaluator&) =
+      delete;
+  CastSystemMemoryPressureEvaluator& operator=(
+      const CastSystemMemoryPressureEvaluator&) = delete;
+
   ~CastSystemMemoryPressureEvaluator() override;
 
   // CastSystemMemoryPressureEvaluatorAdjuster implementation:
@@ -63,8 +69,6 @@
   const int system_reserved_kb_;
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   base::WeakPtrFactory<CastSystemMemoryPressureEvaluator> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastSystemMemoryPressureEvaluator);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/cast_touch_device_manager.h b/chromecast/browser/cast_touch_device_manager.h
index 4944e2b..cee5138 100644
--- a/chromecast/browser/cast_touch_device_manager.h
+++ b/chromecast/browser/cast_touch_device_manager.h
@@ -19,6 +19,10 @@
 class CastTouchDeviceManager : public ui::InputDeviceEventObserver {
  public:
   explicit CastTouchDeviceManager();
+
+  CastTouchDeviceManager(const CastTouchDeviceManager&) = delete;
+  CastTouchDeviceManager& operator=(const CastTouchDeviceManager&) = delete;
+
   ~CastTouchDeviceManager() override;
 
   // ui::InputDeviceEventObserver:
@@ -34,8 +38,6 @@
   int64_t display_id_;
   display::Display::Rotation display_rotation_;
   gfx::Rect native_display_bounds_in_pixel_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastTouchDeviceManager);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/cast_web_contents_browsertest.cc b/chromecast/browser/cast_web_contents_browsertest.cc
index 75e3414..d3bdf572 100644
--- a/chromecast/browser/cast_web_contents_browsertest.cc
+++ b/chromecast/browser/cast_web_contents_browsertest.cc
@@ -104,6 +104,11 @@
 class MockCastWebContentsObserver : public CastWebContentsObserver {
  public:
   MockCastWebContentsObserver() {}
+
+  MockCastWebContentsObserver(const MockCastWebContentsObserver&) = delete;
+  MockCastWebContentsObserver& operator=(const MockCastWebContentsObserver&) =
+      delete;
+
   ~MockCastWebContentsObserver() override = default;
 
   MOCK_METHOD1(PageStateChanged, void(PageState page_state));
@@ -116,9 +121,6 @@
                         settings_manager));
   MOCK_METHOD0(ResourceLoadFailed, void());
   MOCK_METHOD1(UpdateTitle, void(const std::string& title));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockCastWebContentsObserver);
 };
 
 class MockWebContentsDelegate : public content::WebContentsDelegate {
@@ -132,6 +134,10 @@
 class TitleChangeObserver : public CastWebContentsObserver {
  public:
   TitleChangeObserver() = default;
+
+  TitleChangeObserver(const TitleChangeObserver&) = delete;
+  TitleChangeObserver& operator=(const TitleChangeObserver&) = delete;
+
   ~TitleChangeObserver() override = default;
 
   // Spins a Runloop until the title of the page matches the |expected_title|
@@ -163,13 +169,15 @@
   std::string expected_title_;
 
   base::OnceClosure quit_closure_;
-
-  DISALLOW_COPY_AND_ASSIGN(TitleChangeObserver);
 };
 
 class TestMessageReceiver : public blink::WebMessagePort::MessageReceiver {
  public:
   TestMessageReceiver() = default;
+
+  TestMessageReceiver(const TestMessageReceiver&) = delete;
+  TestMessageReceiver& operator=(const TestMessageReceiver&) = delete;
+
   ~TestMessageReceiver() override = default;
 
   void WaitForNextIncomingMessage(
@@ -218,8 +226,6 @@
       message_received_callback_;
 
   base::OnceCallback<void()> on_pipe_error_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestMessageReceiver);
 };
 
 }  // namespace
diff --git a/chromecast/browser/cast_web_contents_impl.h b/chromecast/browser/cast_web_contents_impl.h
index 62d996a..04a4e9a 100644
--- a/chromecast/browser/cast_web_contents_impl.h
+++ b/chromecast/browser/cast_web_contents_impl.h
@@ -53,6 +53,10 @@
  public:
   CastWebContentsImpl(content::WebContents* web_contents,
                       mojom::CastWebViewParamsPtr params);
+
+  CastWebContentsImpl(const CastWebContentsImpl&) = delete;
+  CastWebContentsImpl& operator=(const CastWebContentsImpl&) = delete;
+
   ~CastWebContentsImpl() override;
 
   content::WebContents* web_contents() const override;
@@ -221,8 +225,6 @@
 
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<CastWebContentsImpl> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastWebContentsImpl);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/cast_web_view.h b/chromecast/browser/cast_web_view.h
index d2aa2b19..52eee2b8 100644
--- a/chromecast/browser/cast_web_view.h
+++ b/chromecast/browser/cast_web_view.h
@@ -51,6 +51,10 @@
   };
 
   CastWebView() = default;
+
+  CastWebView(const CastWebView&) = delete;
+  CastWebView& operator=(const CastWebView&) = delete;
+
   virtual ~CastWebView() = default;
 
   virtual CastContentWindow* window() const = 0;
@@ -64,9 +68,6 @@
   void BindReceivers(
       mojo::PendingReceiver<mojom::CastWebContents> web_contents_receiver,
       mojo::PendingReceiver<mojom::CastContentWindow> window_receiver);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastWebView);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/cast_web_view_factory.h b/chromecast/browser/cast_web_view_factory.h
index 3d837946..af1dbce0 100644
--- a/chromecast/browser/cast_web_view_factory.h
+++ b/chromecast/browser/cast_web_view_factory.h
@@ -24,6 +24,10 @@
 class CastWebViewFactory {
  public:
   explicit CastWebViewFactory(content::BrowserContext* browser_context);
+
+  CastWebViewFactory(const CastWebViewFactory&) = delete;
+  CastWebViewFactory& operator=(const CastWebViewFactory&) = delete;
+
   virtual ~CastWebViewFactory();
 
   virtual std::unique_ptr<CastWebView> CreateWebView(
@@ -36,8 +40,6 @@
  protected:
   content::BrowserContext* const browser_context_;
   base::RepeatingCallback<void(CastWebView*, int)> register_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastWebViewFactory);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/devtools/cast_devtools_manager_delegate.h b/chromecast/browser/devtools/cast_devtools_manager_delegate.h
index 113bb80..b1f61ef 100644
--- a/chromecast/browser/devtools/cast_devtools_manager_delegate.h
+++ b/chromecast/browser/devtools/cast_devtools_manager_delegate.h
@@ -25,6 +25,11 @@
   static CastDevToolsManagerDelegate* GetInstance();
 
   CastDevToolsManagerDelegate();
+
+  CastDevToolsManagerDelegate(const CastDevToolsManagerDelegate&) = delete;
+  CastDevToolsManagerDelegate& operator=(const CastDevToolsManagerDelegate&) =
+      delete;
+
   ~CastDevToolsManagerDelegate() override;
 
   void EnableWebContentsForDebugging(content::WebContents* web_contents);
@@ -37,7 +42,6 @@
 
  private:
   std::unordered_set<content::WebContents*> enabled_webcontents_;
-  DISALLOW_COPY_AND_ASSIGN(CastDevToolsManagerDelegate);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/devtools/cast_devtools_manager_delegate_unittest.cc b/chromecast/browser/devtools/cast_devtools_manager_delegate_unittest.cc
index 08e34e3..b3d1d0aa 100644
--- a/chromecast/browser/devtools/cast_devtools_manager_delegate_unittest.cc
+++ b/chromecast/browser/devtools/cast_devtools_manager_delegate_unittest.cc
@@ -25,6 +25,12 @@
   using WebContentsSet = std::unordered_set<content::WebContents*>;
 
   CastDevToolsManagerDelegateTest() {}
+
+  CastDevToolsManagerDelegateTest(const CastDevToolsManagerDelegateTest&) =
+      delete;
+  CastDevToolsManagerDelegateTest& operator=(
+      const CastDevToolsManagerDelegateTest&) = delete;
+
   ~CastDevToolsManagerDelegateTest() override {}
 
   void SetUp() override {
@@ -49,9 +55,6 @@
  protected:
   std::unique_ptr<content::TestContentClientInitializer> initializer_;
   std::unique_ptr<CastDevToolsManagerDelegate> devtools_manager_delegate_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastDevToolsManagerDelegateTest);
 };
 
 TEST_F(CastDevToolsManagerDelegateTest, TestSingletonGetter) {
diff --git a/chromecast/browser/devtools/cast_ui_devtools.h b/chromecast/browser/devtools/cast_ui_devtools.h
index e480ce06b..c57f4b8 100644
--- a/chromecast/browser/devtools/cast_ui_devtools.h
+++ b/chromecast/browser/devtools/cast_ui_devtools.h
@@ -28,6 +28,10 @@
 class CastUIDevTools {
  public:
   explicit CastUIDevTools(network::mojom::NetworkContext* network_context);
+
+  CastUIDevTools(const CastUIDevTools&) = delete;
+  CastUIDevTools& operator=(const CastUIDevTools&) = delete;
+
   ~CastUIDevTools();
 
  private:
@@ -35,8 +39,6 @@
       network::mojom::NetworkContext* network_context) const;
 
   std::unique_ptr<ui_devtools::UiDevToolsServer> devtools_server_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastUIDevTools);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/devtools/remote_debugging_server.cc b/chromecast/browser/devtools/remote_debugging_server.cc
index fe455ebb..34cbb747 100644
--- a/chromecast/browser/devtools/remote_debugging_server.cc
+++ b/chromecast/browser/devtools/remote_debugging_server.cc
@@ -147,6 +147,9 @@
     Observe(contents);
   }
 
+  WebContentsObserver(const WebContentsObserver&) = delete;
+  WebContentsObserver& operator=(const WebContentsObserver&) = delete;
+
   ~WebContentsObserver() override {}
 
   // content::WebContentsObserver implementation:
@@ -158,8 +161,6 @@
 
  private:
   RemoteDebuggingServer* const server_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebContentsObserver);
 };
 
 RemoteDebuggingServer::RemoteDebuggingServer(bool start_immediately)
diff --git a/chromecast/browser/devtools/remote_debugging_server.h b/chromecast/browser/devtools/remote_debugging_server.h
index 51142c0..90009cc 100644
--- a/chromecast/browser/devtools/remote_debugging_server.h
+++ b/chromecast/browser/devtools/remote_debugging_server.h
@@ -24,6 +24,10 @@
 class RemoteDebuggingServer {
  public:
   explicit RemoteDebuggingServer(bool start_immediately);
+
+  RemoteDebuggingServer(const RemoteDebuggingServer&) = delete;
+  RemoteDebuggingServer& operator=(const RemoteDebuggingServer&) = delete;
+
   ~RemoteDebuggingServer();
 
   // Allows this WebContents to be debugged.
@@ -43,8 +47,6 @@
       observers_;
   uint16_t port_;
   bool is_started_;
-
-  DISALLOW_COPY_AND_ASSIGN(RemoteDebuggingServer);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/exo/cast_wm_helper.h b/chromecast/browser/exo/cast_wm_helper.h
index 0552306..aa439a26d 100644
--- a/chromecast/browser/exo/cast_wm_helper.h
+++ b/chromecast/browser/exo/cast_wm_helper.h
@@ -58,6 +58,10 @@
  public:
   CastWMHelper(chromecast::CastWindowManagerAura* cast_window_manager_aura,
                chromecast::CastScreen* cast_screen);
+
+  CastWMHelper(const CastWMHelper&) = delete;
+  CastWMHelper& operator=(const CastWMHelper&) = delete;
+
   ~CastWMHelper() override;
 
   // Overridden from WMHelper
@@ -145,8 +149,6 @@
   CastDisplayObserver display_observer_;
   LifetimeManager lifetime_manager_;
   VSyncTimingManager vsync_timing_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastWMHelper);
 };
 
 }  // namespace exo
diff --git a/chromecast/browser/exo/wayland_server_controller.h b/chromecast/browser/exo/wayland_server_controller.h
index 9a910a1..afe38b0f 100644
--- a/chromecast/browser/exo/wayland_server_controller.h
+++ b/chromecast/browser/exo/wayland_server_controller.h
@@ -26,6 +26,10 @@
 class WaylandServerController {
  public:
   explicit WaylandServerController(CastWindowManagerAura* window_manager);
+
+  WaylandServerController(const WaylandServerController&) = delete;
+  WaylandServerController& operator=(const WaylandServerController&) = delete;
+
   ~WaylandServerController();
 
  private:
@@ -33,8 +37,6 @@
   std::unique_ptr<exo::Display> display_;
   std::unique_ptr<exo::wayland::Server> wayland_server_;
   std::unique_ptr<exo::wayland::WaylandWatcher> wayland_watcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(WaylandServerController);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/extensions/api/automation_internal/chromecast_automation_internal_api_delegate.h b/chromecast/browser/extensions/api/automation_internal/chromecast_automation_internal_api_delegate.h
index cd4d2a4c..76e0c73 100644
--- a/chromecast/browser/extensions/api/automation_internal/chromecast_automation_internal_api_delegate.h
+++ b/chromecast/browser/extensions/api/automation_internal/chromecast_automation_internal_api_delegate.h
@@ -15,6 +15,12 @@
     : public AutomationInternalApiDelegate {
  public:
   ChromecastAutomationInternalApiDelegate();
+
+  ChromecastAutomationInternalApiDelegate(
+      const ChromecastAutomationInternalApiDelegate&) = delete;
+  ChromecastAutomationInternalApiDelegate& operator=(
+      const ChromecastAutomationInternalApiDelegate&) = delete;
+
   ~ChromecastAutomationInternalApiDelegate() override;
 
   bool CanRequestAutomation(const Extension* extension,
@@ -34,8 +40,6 @@
   void SetAutomationEventRouterInterface(
       AutomationEventRouterInterface* router) override;
   content::BrowserContext* GetActiveUserContext() override;
-
-  DISALLOW_COPY_AND_ASSIGN(ChromecastAutomationInternalApiDelegate);
 };
 
 }  // namespace extensions
diff --git a/chromecast/browser/extensions/cast_extension_host_delegate.h b/chromecast/browser/extensions/cast_extension_host_delegate.h
index 097d01270..9d18057 100644
--- a/chromecast/browser/extensions/cast_extension_host_delegate.h
+++ b/chromecast/browser/extensions/cast_extension_host_delegate.h
@@ -14,6 +14,11 @@
 class CastExtensionHostDelegate : public ExtensionHostDelegate {
  public:
   CastExtensionHostDelegate();
+
+  CastExtensionHostDelegate(const CastExtensionHostDelegate&) = delete;
+  CastExtensionHostDelegate& operator=(const CastExtensionHostDelegate&) =
+      delete;
+
   ~CastExtensionHostDelegate() override;
 
   // ExtensionHostDelegate implementation.
@@ -38,9 +43,6 @@
       const viz::SurfaceId& surface_id,
       const gfx::Size& natural_size) override;
   void ExitPictureInPicture() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionHostDelegate);
 };
 
 }  // namespace extensions
diff --git a/chromecast/browser/extensions/cast_extension_system.h b/chromecast/browser/extensions/cast_extension_system.h
index 899ab11..61c6200 100644
--- a/chromecast/browser/extensions/cast_extension_system.h
+++ b/chromecast/browser/extensions/cast_extension_system.h
@@ -32,6 +32,10 @@
                             public ExtensionRegistrar::Delegate {
  public:
   explicit CastExtensionSystem(content::BrowserContext* browser_context);
+
+  CastExtensionSystem(const CastExtensionSystem&) = delete;
+  CastExtensionSystem& operator=(const CastExtensionSystem&) = delete;
+
   ~CastExtensionSystem() override;
 
   // Loads an unpacked extension from a directory. Returns the extension on
@@ -136,8 +140,6 @@
   base::OneShotEvent ready_;
 
   base::WeakPtrFactory<CastExtensionSystem> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionSystem);
 };
 
 }  // namespace extensions
diff --git a/chromecast/browser/extensions/cast_extension_web_contents_observer.h b/chromecast/browser/extensions/cast_extension_web_contents_observer.h
index 569f7b13..4acccea 100644
--- a/chromecast/browser/extensions/cast_extension_web_contents_observer.h
+++ b/chromecast/browser/extensions/cast_extension_web_contents_observer.h
@@ -16,6 +16,11 @@
     : public ExtensionWebContentsObserver,
       public content::WebContentsUserData<CastExtensionWebContentsObserver> {
  public:
+  CastExtensionWebContentsObserver(const CastExtensionWebContentsObserver&) =
+      delete;
+  CastExtensionWebContentsObserver& operator=(
+      const CastExtensionWebContentsObserver&) = delete;
+
   ~CastExtensionWebContentsObserver() override;
 
   // Creates and initializes an instance of this class for the given
@@ -28,8 +33,6 @@
   explicit CastExtensionWebContentsObserver(content::WebContents* web_contents);
 
   WEB_CONTENTS_USER_DATA_KEY_DECL();
-
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionWebContentsObserver);
 };
 
 }  // namespace extensions
diff --git a/chromecast/browser/extensions/cast_extensions_api_client.h b/chromecast/browser/extensions/cast_extensions_api_client.h
index 816f45a9..11591ddb 100644
--- a/chromecast/browser/extensions/cast_extensions_api_client.h
+++ b/chromecast/browser/extensions/cast_extensions_api_client.h
@@ -17,6 +17,10 @@
 class CastExtensionsAPIClient : public ExtensionsAPIClient {
  public:
   CastExtensionsAPIClient();
+
+  CastExtensionsAPIClient(const CastExtensionsAPIClient&) = delete;
+  CastExtensionsAPIClient& operator=(const CastExtensionsAPIClient&) = delete;
+
   ~CastExtensionsAPIClient() override;
 
   // ExtensionsAPIClient implementation.
@@ -31,8 +35,6 @@
   std::unique_ptr<MessagingDelegate> messaging_delegate_;
   std::unique_ptr<extensions::ChromecastAutomationInternalApiDelegate>
       extensions_automation_api_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionsAPIClient);
 };
 
 }  // namespace extensions
diff --git a/chromecast/browser/extensions/cast_extensions_browser_api_provider.h b/chromecast/browser/extensions/cast_extensions_browser_api_provider.h
index d2433cc..f6bb8e4a 100644
--- a/chromecast/browser/extensions/cast_extensions_browser_api_provider.h
+++ b/chromecast/browser/extensions/cast_extensions_browser_api_provider.h
@@ -13,12 +13,15 @@
 class CastExtensionsBrowserAPIProvider : public ExtensionsBrowserAPIProvider {
  public:
   CastExtensionsBrowserAPIProvider();
+
+  CastExtensionsBrowserAPIProvider(const CastExtensionsBrowserAPIProvider&) =
+      delete;
+  CastExtensionsBrowserAPIProvider& operator=(
+      const CastExtensionsBrowserAPIProvider&) = delete;
+
   ~CastExtensionsBrowserAPIProvider() override;
 
   void RegisterExtensionFunctions(ExtensionFunctionRegistry* registry) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionsBrowserAPIProvider);
 };
 
 }  // namespace extensions
diff --git a/chromecast/browser/extensions/cast_extensions_browser_client.h b/chromecast/browser/extensions/cast_extensions_browser_client.h
index e126819..0d43761 100644
--- a/chromecast/browser/extensions/cast_extensions_browser_client.h
+++ b/chromecast/browser/extensions/cast_extensions_browser_client.h
@@ -38,6 +38,11 @@
       content::BrowserContext* context,
       PrefService* pref_service,
       chromecast::shell::CastNetworkContexts* cast_network_contexts);
+
+  CastExtensionsBrowserClient(const CastExtensionsBrowserClient&) = delete;
+  CastExtensionsBrowserClient& operator=(const CastExtensionsBrowserClient&) =
+      delete;
+
   ~CastExtensionsBrowserClient() override;
 
   // ExtensionsBrowserClient overrides:
@@ -134,8 +139,6 @@
   std::unique_ptr<ExtensionsAPIClient> api_client_;
 
   std::unique_ptr<KioskDelegate> kiosk_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionsBrowserClient);
 };
 
 }  // namespace extensions
diff --git a/chromecast/browser/general_audience_browsing_navigation_throttle.h b/chromecast/browser/general_audience_browsing_navigation_throttle.h
index f6c3ac8..7c89594 100644
--- a/chromecast/browser/general_audience_browsing_navigation_throttle.h
+++ b/chromecast/browser/general_audience_browsing_navigation_throttle.h
@@ -23,6 +23,12 @@
   GeneralAudienceBrowsingNavigationThrottle(
       content::NavigationHandle* navigation_handle,
       GeneralAudienceBrowsingService* general_audience_browsing_service);
+
+  GeneralAudienceBrowsingNavigationThrottle(
+      const GeneralAudienceBrowsingNavigationThrottle&) = delete;
+  GeneralAudienceBrowsingNavigationThrottle& operator=(
+      const GeneralAudienceBrowsingNavigationThrottle&) = delete;
+
   ~GeneralAudienceBrowsingNavigationThrottle() override;
 
   // NavigationThrottle overrides.
@@ -48,8 +54,6 @@
 
   base::WeakPtrFactory<GeneralAudienceBrowsingNavigationThrottle>
       weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(GeneralAudienceBrowsingNavigationThrottle);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/general_audience_browsing_service.h b/chromecast/browser/general_audience_browsing_service.h
index d57e90a..0ff32a7 100644
--- a/chromecast/browser/general_audience_browsing_service.h
+++ b/chromecast/browser/general_audience_browsing_service.h
@@ -33,6 +33,12 @@
   GeneralAudienceBrowsingService(
       external_service_support::ExternalConnector* connector,
       scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory);
+
+  GeneralAudienceBrowsingService(const GeneralAudienceBrowsingService&) =
+      delete;
+  GeneralAudienceBrowsingService& operator=(
+      const GeneralAudienceBrowsingService&) = delete;
+
   ~GeneralAudienceBrowsingService() override;
 
   // Starts a call to the Safe Search API for the given URL to determine whether
@@ -61,8 +67,6 @@
       general_audience_browsing_api_key_observer_receiver_{this};
   mojo::Remote<mojom::GeneralAudienceBrowsingAPIKeySubject>
       general_audience_browsing_api_key_subject_remote_;
-
-  DISALLOW_COPY_AND_ASSIGN(GeneralAudienceBrowsingService);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/lru_renderer_cache.h b/chromecast/browser/lru_renderer_cache.h
index 0e94ed5..5253e1d 100644
--- a/chromecast/browser/lru_renderer_cache.h
+++ b/chromecast/browser/lru_renderer_cache.h
@@ -36,6 +36,10 @@
  public:
   LRURendererCache(content::BrowserContext* browser_context,
                    size_t max_renderers);
+
+  LRURendererCache(const LRURendererCache&) = delete;
+  LRURendererCache& operator=(const LRURendererCache&) = delete;
+
   virtual ~LRURendererCache();
 
   // Returns a pre-launched renderer. Returns nullptr if a cached renderer isn't
@@ -72,8 +76,6 @@
   RendererPrelauncherFactory* factory_for_testing_ = nullptr;
 
   base::WeakPtrFactory<LRURendererCache> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(LRURendererCache);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/media/media_caps_impl.h b/chromecast/browser/media/media_caps_impl.h
index 0bcca4d0..744dfa2 100644
--- a/chromecast/browser/media/media_caps_impl.h
+++ b/chromecast/browser/media/media_caps_impl.h
@@ -22,6 +22,10 @@
 class MediaCapsImpl : public mojom::MediaCaps {
  public:
   MediaCapsImpl();
+
+  MediaCapsImpl(const MediaCapsImpl&) = delete;
+  MediaCapsImpl& operator=(const MediaCapsImpl&) = delete;
+
   ~MediaCapsImpl() override;
 
   void Initialize();
@@ -54,8 +58,6 @@
   std::vector<CodecProfileLevel> codec_profile_levels_;
   mojo::RemoteSet<mojom::MediaCapsObserver> observers_;
   mojo::ReceiverSet<mojom::MediaCaps> receivers_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaCapsImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/browser/memory_pressure_controller_impl.h b/chromecast/browser/memory_pressure_controller_impl.h
index 9a94b9d6..ea00857 100644
--- a/chromecast/browser/memory_pressure_controller_impl.h
+++ b/chromecast/browser/memory_pressure_controller_impl.h
@@ -17,6 +17,11 @@
 class MemoryPressureControllerImpl : public mojom::MemoryPressureController {
  public:
   MemoryPressureControllerImpl();
+
+  MemoryPressureControllerImpl(const MemoryPressureControllerImpl&) = delete;
+  MemoryPressureControllerImpl& operator=(const MemoryPressureControllerImpl&) =
+      delete;
+
   ~MemoryPressureControllerImpl() override;
 
   void AddReceiver(
@@ -34,8 +39,6 @@
   mojo::ReceiverSet<mojom::MemoryPressureController> receivers_;
 
   std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
-
-  DISALLOW_COPY_AND_ASSIGN(MemoryPressureControllerImpl);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/metrics/cast_browser_metrics.h b/chromecast/browser/metrics/cast_browser_metrics.h
index 947f4732..211c4a0 100644
--- a/chromecast/browser/metrics/cast_browser_metrics.h
+++ b/chromecast/browser/metrics/cast_browser_metrics.h
@@ -21,6 +21,10 @@
  public:
   explicit CastBrowserMetrics(
       std::unique_ptr<CastMetricsServiceClient> metrics_service_client);
+
+  CastBrowserMetrics(const CastBrowserMetrics&) = delete;
+  CastBrowserMetrics& operator=(const CastBrowserMetrics&) = delete;
+
   ~CastBrowserMetrics();
   void Initialize();
   void Finalize();
@@ -42,8 +46,6 @@
   ExternalMetrics* external_metrics_ = nullptr;
   ExternalMetrics* platform_metrics_ = nullptr;
 #endif  // defined(OS_LINUX) || defined(OS_CHROMEOS)
-
-  DISALLOW_COPY_AND_ASSIGN(CastBrowserMetrics);
 };
 
 }  // namespace metrics
diff --git a/chromecast/browser/metrics/cast_stability_metrics_provider.h b/chromecast/browser/metrics/cast_stability_metrics_provider.h
index 966d647..1956297c 100644
--- a/chromecast/browser/metrics/cast_stability_metrics_provider.h
+++ b/chromecast/browser/metrics/cast_stability_metrics_provider.h
@@ -38,6 +38,11 @@
 
   CastStabilityMetricsProvider(::metrics::MetricsService* metrics_service,
                                PrefService* pref_service);
+
+  CastStabilityMetricsProvider(const CastStabilityMetricsProvider&) = delete;
+  CastStabilityMetricsProvider& operator=(const CastStabilityMetricsProvider&) =
+      delete;
+
   ~CastStabilityMetricsProvider() override;
 
   // metrics::MetricsDataProvider implementation:
@@ -80,8 +85,6 @@
   ::metrics::MetricsService* metrics_service_;
 
   PrefService* const pref_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastStabilityMetricsProvider);
 };
 
 }  // namespace metrics
diff --git a/chromecast/browser/renderer_prelauncher.h b/chromecast/browser/renderer_prelauncher.h
index eb17e8b..b6395066 100644
--- a/chromecast/browser/renderer_prelauncher.h
+++ b/chromecast/browser/renderer_prelauncher.h
@@ -26,6 +26,10 @@
  public:
   RendererPrelauncher(content::BrowserContext* browser_context,
                       const GURL& gurl);
+
+  RendererPrelauncher(const RendererPrelauncher&) = delete;
+  RendererPrelauncher& operator=(const RendererPrelauncher&) = delete;
+
   ~RendererPrelauncher() override;
 
   virtual void Prelaunch();
@@ -44,8 +48,6 @@
   scoped_refptr<content::SiteInstance> site_instance_;
   const GURL gurl_;
   int32_t rph_routing_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(RendererPrelauncher);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/renderer_prelauncher_test.cc b/chromecast/browser/renderer_prelauncher_test.cc
index fc0fc29..5d35e5b 100644
--- a/chromecast/browser/renderer_prelauncher_test.cc
+++ b/chromecast/browser/renderer_prelauncher_test.cc
@@ -25,6 +25,10 @@
 class RendererPrelauncherTest : public content::BrowserTestBase {
  public:
   RendererPrelauncherTest() {}
+
+  RendererPrelauncherTest(const RendererPrelauncherTest&) = delete;
+  RendererPrelauncherTest& operator=(const RendererPrelauncherTest&) = delete;
+
   ~RendererPrelauncherTest() override {}
 
  protected:
@@ -32,9 +36,6 @@
   void SetUp() override;
   void PreRunTestOnMainThread() override;
   void PostRunTestOnMainThread() override {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(RendererPrelauncherTest);
 };
 
 void RendererPrelauncherTest::SetUp() {
diff --git a/chromecast/browser/service/cast_service_simple.h b/chromecast/browser/service/cast_service_simple.h
index fc05a8a..c1d70bd 100644
--- a/chromecast/browser/service/cast_service_simple.h
+++ b/chromecast/browser/service/cast_service_simple.h
@@ -30,6 +30,10 @@
  public:
   CastServiceSimple(content::BrowserContext* browser_context,
                     CastWindowManager* window_manager);
+
+  CastServiceSimple(const CastServiceSimple&) = delete;
+  CastServiceSimple& operator=(const CastServiceSimple&) = delete;
+
   ~CastServiceSimple() override;
 
  protected:
@@ -53,7 +57,6 @@
   GURL startup_url_;
 
   base::WeakPtrFactory<CastServiceSimple> weak_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(CastServiceSimple);
 };
 
 }  // namespace shell
diff --git a/chromecast/browser/service_manager_connection.cc b/chromecast/browser/service_manager_connection.cc
index 8657eda..d33968d 100644
--- a/chromecast/browser/service_manager_connection.cc
+++ b/chromecast/browser/service_manager_connection.cc
@@ -84,6 +84,9 @@
       base::CurrentThread::Get()->AddDestructionObserver(this);
     }
 
+    MessageLoopObserver(const MessageLoopObserver&) = delete;
+    MessageLoopObserver& operator=(const MessageLoopObserver&) = delete;
+
     ~MessageLoopObserver() override {
       base::CurrentThread::Get()->RemoveDestructionObserver(this);
     }
@@ -109,8 +112,6 @@
 
     bool is_active_ = true;
     base::WeakPtr<IOThreadContext> context_;
-
-    DISALLOW_COPY_AND_ASSIGN(MessageLoopObserver);
   };
 
   ~IOThreadContext() override {}
diff --git a/chromecast/browser/service_manager_context.cc b/chromecast/browser/service_manager_context.cc
index 2f8d163..2873d0b3 100644
--- a/chromecast/browser/service_manager_context.cc
+++ b/chromecast/browser/service_manager_context.cc
@@ -106,6 +106,12 @@
     : public service_manager::ServiceProcessHost {
  public:
   ContentChildServiceProcessHost() = default;
+
+  ContentChildServiceProcessHost(const ContentChildServiceProcessHost&) =
+      delete;
+  ContentChildServiceProcessHost& operator=(
+      const ContentChildServiceProcessHost&) = delete;
+
   ~ContentChildServiceProcessHost() override = default;
 
   // service_manager::ServiceProcessHost:
@@ -122,9 +128,6 @@
         std::move(callback));
     return remote;
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ContentChildServiceProcessHost);
 };
 
 // A ServiceProcessHost implementation which uses the Service Manager's builtin
@@ -135,6 +138,11 @@
  public:
   explicit ServiceExecutableProcessHost(const base::FilePath& executable_path)
       : launcher_(nullptr, executable_path) {}
+
+  ServiceExecutableProcessHost(const ServiceExecutableProcessHost&) = delete;
+  ServiceExecutableProcessHost& operator=(const ServiceExecutableProcessHost&) =
+      delete;
+
   ~ServiceExecutableProcessHost() override = default;
 
   // service_manager::ServiceProcessHost:
@@ -150,8 +158,6 @@
 
  private:
   service_manager::ServiceProcessLauncher launcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceExecutableProcessHost);
 };
 
 using ServiceRequestHandler = base::RepeatingCallback<void(
@@ -171,6 +177,11 @@
       ServiceRequestHandler main_thread_request_handler)
       : main_thread_task_runner_(main_thread_task_runner),
         main_thread_request_handler_(std::move(main_thread_request_handler)) {}
+
+  BrowserServiceManagerDelegate(const BrowserServiceManagerDelegate&) = delete;
+  BrowserServiceManagerDelegate& operator=(
+      const BrowserServiceManagerDelegate&) = delete;
+
   ~BrowserServiceManagerDelegate() override = default;
 
   // service_manager::ServiceManager::Delegate:
@@ -204,8 +215,6 @@
  private:
   const scoped_refptr<base::SequencedTaskRunner> main_thread_task_runner_;
   const ServiceRequestHandler main_thread_request_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserServiceManagerDelegate);
 };
 
 }  // namespace
diff --git a/chromecast/browser/service_manager_context.h b/chromecast/browser/service_manager_context.h
index 79440021..2a86c02 100644
--- a/chromecast/browser/service_manager_context.h
+++ b/chromecast/browser/service_manager_context.h
@@ -34,6 +34,10 @@
       shell::CastContentBrowserClient* cast_content_browser_client,
       scoped_refptr<base::SingleThreadTaskRunner>
           service_manager_thread_task_runner);
+
+  ServiceManagerContext(const ServiceManagerContext&) = delete;
+  ServiceManagerContext& operator=(const ServiceManagerContext&) = delete;
+
   ~ServiceManagerContext();
 
   // Returns a service_manager::Connector that can be used on the IO thread.
@@ -54,8 +58,6 @@
       service_manager_thread_task_runner_;
   scoped_refptr<InProcessServiceManagerContext> in_process_context_;
   base::WeakPtrFactory<ServiceManagerContext> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(ServiceManagerContext);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/test/cast_features_browsertest.cc b/chromecast/browser/test/cast_features_browsertest.cc
index 132c08e04..e0e17de3 100644
--- a/chromecast/browser/test/cast_features_browsertest.cc
+++ b/chromecast/browser/test/cast_features_browsertest.cc
@@ -110,6 +110,10 @@
 class CastFeaturesBrowserTest : public CastBrowserTest {
  public:
   CastFeaturesBrowserTest() { SetupFeatures(); }
+
+  CastFeaturesBrowserTest(const CastFeaturesBrowserTest&) = delete;
+  CastFeaturesBrowserTest& operator=(const CastFeaturesBrowserTest&) = delete;
+
   ~CastFeaturesBrowserTest() override { chromecast::ResetCastFeaturesForTesting(); }
 
   static PrefService* pref_service() {
@@ -154,9 +158,6 @@
     pref_service()->Set(prefs::kActiveDCSExperiments, base::ListValue());
     pref_service()->CommitPendingWrite();
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastFeaturesBrowserTest);
 };
 
 // Test that set features activate on the next boot. Part 1 of 3.
diff --git a/chromecast/browser/ui/aura/accessibility/ax_tree_source_aura.h b/chromecast/browser/ui/aura/accessibility/ax_tree_source_aura.h
index fbf2524..29dd40eb 100644
--- a/chromecast/browser/ui/aura/accessibility/ax_tree_source_aura.h
+++ b/chromecast/browser/ui/aura/accessibility/ax_tree_source_aura.h
@@ -15,6 +15,10 @@
   AXTreeSourceAura(views::AXAuraObjWrapper* root,
                    const ui::AXTreeID& tree_id,
                    views::AXAuraObjCache* cache);
+
+  AXTreeSourceAura(const AXTreeSourceAura&) = delete;
+  AXTreeSourceAura& operator=(const AXTreeSourceAura&) = delete;
+
   ~AXTreeSourceAura() override;
 
   // AXTreeSource:
@@ -24,8 +28,6 @@
 
  private:
   views::AXAuraObjCache* cache_;
-
-  DISALLOW_COPY_AND_ASSIGN(AXTreeSourceAura);
 };
 
 #endif  // CHROMECAST_BROWSER_UI_AURA_ACCESSIBILITY_AX_TREE_SOURCE_AURA_H_
diff --git a/chromecast/browser/webview/cast_app_controller.h b/chromecast/browser/webview/cast_app_controller.h
index 9a5ff42..39f0494 100644
--- a/chromecast/browser/webview/cast_app_controller.h
+++ b/chromecast/browser/webview/cast_app_controller.h
@@ -14,6 +14,10 @@
 class CastAppController : public WebContentController {
  public:
   CastAppController(Client* client, content::WebContents* contents);
+
+  CastAppController(const CastAppController&) = delete;
+  CastAppController& operator=(const CastAppController&) = delete;
+
   ~CastAppController() override;
 
   void Destroy() override;
@@ -26,8 +30,6 @@
   void WebContentsDestroyed() override;
 
   content::WebContents* contents_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastAppController);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/cast_app_rpc_instance.h b/chromecast/browser/webview/cast_app_rpc_instance.h
index af78e42..08b78e28 100644
--- a/chromecast/browser/webview/cast_app_rpc_instance.h
+++ b/chromecast/browser/webview/cast_app_rpc_instance.h
@@ -21,6 +21,10 @@
                      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
                      WebviewWindowManager* window_manager,
                      base::WeakPtr<WebContentsProvider> web_contents_provider);
+
+  CastAppRpcInstance(const CastAppRpcInstance&) = delete;
+  CastAppRpcInstance& operator=(const CastAppRpcInstance&) = delete;
+
   ~CastAppRpcInstance() override;
 
  protected:
@@ -32,8 +36,6 @@
   void WebContentsDestroyed() override;
   webview::PlatformViewsService::AsyncService* service_;
   base::WeakPtr<WebContentsProvider> web_contents_provider_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastAppRpcInstance);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/client/webview.h b/chromecast/browser/webview/client/webview.h
index 3d03585f..c9132e8a 100644
--- a/chromecast/browser/webview/client/webview.h
+++ b/chromecast/browser/webview/client/webview.h
@@ -31,6 +31,10 @@
   };
 
   WebviewClient();
+
+  WebviewClient(const WebviewClient&) = delete;
+  WebviewClient& operator=(const WebviewClient&) = delete;
+
   ~WebviewClient() override;
   bool HasAvailableBuffer();
   void Run(const InitParams& params, const std::string& channel_directory);
@@ -135,7 +139,6 @@
   base::RunLoop run_loop_;
 
   std::unique_ptr<chromecast::webview::PlatformViewsService::Stub> stub_;
-  DISALLOW_COPY_AND_ASSIGN(WebviewClient);
 };
 
 }  // namespace client
diff --git a/chromecast/browser/webview/js_channel_service.cc b/chromecast/browser/webview/js_channel_service.cc
index 96e039f..3fb4077 100644
--- a/chromecast/browser/webview/js_channel_service.cc
+++ b/chromecast/browser/webview/js_channel_service.cc
@@ -18,6 +18,10 @@
 class JsChannelImpl : public mojom::JsChannel {
  public:
   JsChannelImpl(const std::string& channel, JsChannelCallback callback);
+
+  JsChannelImpl(const JsChannelImpl&) = delete;
+  JsChannelImpl& operator=(const JsChannelImpl&) = delete;
+
   ~JsChannelImpl() override;
 
  private:
@@ -25,8 +29,6 @@
 
   std::string channel_;
   JsChannelCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(JsChannelImpl);
 };
 
 // The web contents and channel implementations don't know about each other
diff --git a/chromecast/browser/webview/js_channel_service.h b/chromecast/browser/webview/js_channel_service.h
index 9795120a6..f5cb20e 100644
--- a/chromecast/browser/webview/js_channel_service.h
+++ b/chromecast/browser/webview/js_channel_service.h
@@ -31,6 +31,10 @@
       scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   explicit JsChannelService(int process_id);
+
+  JsChannelService(const JsChannelService&) = delete;
+  JsChannelService& operator=(const JsChannelService&) = delete;
+
   ~JsChannelService() override;
 
  private:
@@ -39,8 +43,6 @@
                 mojo::PendingRemote<mojom::JsChannelClient> client) override;
 
   int process_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(JsChannelService);
 };
 
 class JsClientInstance {
diff --git a/chromecast/browser/webview/platform_views_grpc_service.h b/chromecast/browser/webview/platform_views_grpc_service.h
index 529de50..bf5b7df 100644
--- a/chromecast/browser/webview/platform_views_grpc_service.h
+++ b/chromecast/browser/webview/platform_views_grpc_service.h
@@ -26,6 +26,11 @@
       scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
       base::WeakPtr<WebContentsProvider> web_contents_provider,
       bool enabled_for_dev);
+
+  PlatformViewsAsyncService(const PlatformViewsAsyncService&) = delete;
+  PlatformViewsAsyncService& operator=(const PlatformViewsAsyncService&) =
+      delete;
+
   ~PlatformViewsAsyncService() override;
 
  private:
@@ -44,8 +49,6 @@
   WebviewWindowManager window_manager_;
   base::WeakPtr<WebContentsProvider> web_contents_provider_;
   bool enabled_for_dev_;
-
-  DISALLOW_COPY_AND_ASSIGN(PlatformViewsAsyncService);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/platform_views_rpc_instance.h b/chromecast/browser/webview/platform_views_rpc_instance.h
index 7618514..2d5d1d3 100644
--- a/chromecast/browser/webview/platform_views_rpc_instance.h
+++ b/chromecast/browser/webview/platform_views_rpc_instance.h
@@ -33,6 +33,10 @@
       grpc::ServerCompletionQueue* cq,
       scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       WebviewWindowManager* window_manager);
+
+  PlatformViewsRpcInstance(const PlatformViewsRpcInstance&) = delete;
+  PlatformViewsRpcInstance& operator=(const PlatformViewsRpcInstance&) = delete;
+
   ~PlatformViewsRpcInstance() override;
 
  protected:
@@ -88,8 +92,6 @@
   std::deque<std::unique_ptr<webview::WebviewResponse>> pending_messages_;
 
   grpc::WriteOptions write_options_;
-
-  DISALLOW_COPY_AND_ASSIGN(PlatformViewsRpcInstance);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/web_content_controller.h b/chromecast/browser/webview/web_content_controller.h
index 16a9bb8..78efc65 100644
--- a/chromecast/browser/webview/web_content_controller.h
+++ b/chromecast/browser/webview/web_content_controller.h
@@ -56,6 +56,10 @@
   };
 
   explicit WebContentController(Client* client);
+
+  WebContentController(const WebContentController&) = delete;
+  WebContentController& operator=(const WebContentController&) = delete;
+
   ~WebContentController() override;
 
   virtual void Destroy() = 0;
@@ -173,22 +177,22 @@
   std::unique_ptr<ui::InputMethodObserver> input_method_observer_;
 
   base::WeakPtrFactory<WebContentController> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(WebContentController);
 };
 
 class WebContentJsChannels
     : public base::SupportsWeakPtr<WebContentJsChannels> {
  public:
   explicit WebContentJsChannels(WebContentController::Client* client);
+
+  WebContentJsChannels(const WebContentJsChannels&) = delete;
+  WebContentJsChannels& operator=(const WebContentJsChannels&) = delete;
+
   ~WebContentJsChannels();
 
   void SendMessage(const std::string& channel, const std::string& message);
 
  private:
   WebContentController::Client* client_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebContentJsChannels);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/webview_controller.h b/chromecast/browser/webview/webview_controller.h
index 0c2aa392..036bc00e 100644
--- a/chromecast/browser/webview/webview_controller.h
+++ b/chromecast/browser/webview/webview_controller.h
@@ -42,6 +42,10 @@
   WebviewController(std::unique_ptr<content::BrowserContext> browser_context,
                     Client* client,
                     bool enabled_for_dev);
+
+  WebviewController(const WebviewController&) = delete;
+  WebviewController& operator=(const WebviewController&) = delete;
+
   ~WebviewController() override;
 
   // Returns a navigation throttle for the current navigation request, if one is
@@ -111,8 +115,6 @@
       nullptr;  // Not owned.
 
   base::WeakPtrFactory<WebviewController> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(WebviewController);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/webview_navigation_throttle.h b/chromecast/browser/webview/webview_navigation_throttle.h
index 8483144..b145970 100644
--- a/chromecast/browser/webview/webview_navigation_throttle.h
+++ b/chromecast/browser/webview/webview_navigation_throttle.h
@@ -23,6 +23,10 @@
   WebviewNavigationThrottle(content::NavigationHandle* handle,
                             base::WeakPtr<WebviewController> controller);
 
+  WebviewNavigationThrottle(const WebviewNavigationThrottle&) = delete;
+  WebviewNavigationThrottle& operator=(const WebviewNavigationThrottle&) =
+      delete;
+
   ~WebviewNavigationThrottle() override;
 
   ThrottleCheckResult WillStartRequest() override;
@@ -34,8 +38,6 @@
 
  private:
   base::WeakPtr<WebviewController> controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebviewNavigationThrottle);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/webview_rpc_instance.h b/chromecast/browser/webview/webview_rpc_instance.h
index 7fbe56d8..f5f1e60 100644
--- a/chromecast/browser/webview/webview_rpc_instance.h
+++ b/chromecast/browser/webview/webview_rpc_instance.h
@@ -16,6 +16,10 @@
                      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
                      WebviewWindowManager* window_manager,
                      bool enabled_for_dev);
+
+  WebviewRpcInstance(const WebviewRpcInstance&) = delete;
+  WebviewRpcInstance& operator=(const WebviewRpcInstance&) = delete;
+
   ~WebviewRpcInstance() override;
 
  protected:
@@ -26,8 +30,6 @@
   void CreateWebview(int app_id, int window_id, bool incognito);
   webview::PlatformViewsService::AsyncService* platform_views_service_;
   bool enabled_for_dev_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(WebviewRpcInstance);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/browser/webview/webview_window_manager.h b/chromecast/browser/webview/webview_window_manager.h
index 71c812d6..b8c8ed29 100644
--- a/chromecast/browser/webview/webview_window_manager.h
+++ b/chromecast/browser/webview/webview_window_manager.h
@@ -27,6 +27,10 @@
   };
 
   explicit WebviewWindowManager();
+
+  WebviewWindowManager(const WebviewWindowManager&) = delete;
+  WebviewWindowManager& operator=(const WebviewWindowManager&) = delete;
+
   ~WebviewWindowManager() override;
 
   void AddObserver(Observer* observer);
@@ -43,8 +47,6 @@
   std::vector<aura::Window*> observed_windows_;
 
   base::ObserverList<Observer>::Unchecked observers_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebviewWindowManager);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/common/activity_filtering_url_loader_throttle.h b/chromecast/common/activity_filtering_url_loader_throttle.h
index 22414504..4fba935 100644
--- a/chromecast/common/activity_filtering_url_loader_throttle.h
+++ b/chromecast/common/activity_filtering_url_loader_throttle.h
@@ -20,6 +20,12 @@
 class ActivityFilteringURLLoaderThrottle : public blink::URLLoaderThrottle {
  public:
   explicit ActivityFilteringURLLoaderThrottle(ActivityUrlFilter* filter);
+
+  ActivityFilteringURLLoaderThrottle(
+      const ActivityFilteringURLLoaderThrottle&) = delete;
+  ActivityFilteringURLLoaderThrottle& operator=(
+      const ActivityFilteringURLLoaderThrottle&) = delete;
+
   ~ActivityFilteringURLLoaderThrottle() override;
 
   // content::URLLoaderThrottle implementation:
@@ -40,8 +46,6 @@
   void FilterURL(const GURL& url);
 
   ActivityUrlFilter* url_filter_;
-
-  DISALLOW_COPY_AND_ASSIGN(ActivityFilteringURLLoaderThrottle);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/common/activity_url_filter.h b/chromecast/common/activity_url_filter.h
index d1492eb2..f8b31049 100644
--- a/chromecast/common/activity_url_filter.h
+++ b/chromecast/common/activity_url_filter.h
@@ -19,6 +19,10 @@
  public:
   // |url_filters| are applied to network requests from the Activity.
   explicit ActivityUrlFilter(const std::vector<std::string>& url_filters);
+
+  ActivityUrlFilter(const ActivityUrlFilter&) = delete;
+  ActivityUrlFilter& operator=(const ActivityUrlFilter&) = delete;
+
   ~ActivityUrlFilter();
 
   // Returns true if the given url matches to any whitelisted URL.
@@ -26,8 +30,6 @@
 
  private:
   std::unique_ptr<url_matcher::URLMatcher> url_matcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(ActivityUrlFilter);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/common/cast_extensions_api_provider.h b/chromecast/common/cast_extensions_api_provider.h
index 784713b6..a21e7b7 100644
--- a/chromecast/common/cast_extensions_api_provider.h
+++ b/chromecast/common/cast_extensions_api_provider.h
@@ -13,6 +13,11 @@
 class CastExtensionsAPIProvider : public ExtensionsAPIProvider {
  public:
   CastExtensionsAPIProvider();
+
+  CastExtensionsAPIProvider(const CastExtensionsAPIProvider&) = delete;
+  CastExtensionsAPIProvider& operator=(const CastExtensionsAPIProvider&) =
+      delete;
+
   ~CastExtensionsAPIProvider() override;
 
   // ExtensionsAPIProvider:
@@ -25,9 +30,6 @@
   base::StringPiece GetAPISchema(const std::string& name) override;
   void RegisterPermissions(PermissionsInfo* permissions_info) override;
   void RegisterManifestHandlers() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionsAPIProvider);
 };
 
 }  // namespace extensions
diff --git a/chromecast/common/cast_extensions_client.cc b/chromecast/common/cast_extensions_client.cc
index 770e9cb..3973d61 100644
--- a/chromecast/common/cast_extensions_client.cc
+++ b/chromecast/common/cast_extensions_client.cc
@@ -34,6 +34,12 @@
 class ShellPermissionMessageProvider : public PermissionMessageProvider {
  public:
   ShellPermissionMessageProvider() {}
+
+  ShellPermissionMessageProvider(const ShellPermissionMessageProvider&) =
+      delete;
+  ShellPermissionMessageProvider& operator=(
+      const ShellPermissionMessageProvider&) = delete;
+
   ~ShellPermissionMessageProvider() override {}
 
   // PermissionMessageProvider implementation.
@@ -55,9 +61,6 @@
       Manifest::Type extension_type) const override {
     return PermissionIDSet();
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ShellPermissionMessageProvider);
 };
 
 }  // namespace
diff --git a/chromecast/common/cast_extensions_client.h b/chromecast/common/cast_extensions_client.h
index 77e6447..e5c3f35 100644
--- a/chromecast/common/cast_extensions_client.h
+++ b/chromecast/common/cast_extensions_client.h
@@ -16,6 +16,10 @@
 class CastExtensionsClient : public ExtensionsClient {
  public:
   CastExtensionsClient();
+
+  CastExtensionsClient(const CastExtensionsClient&) = delete;
+  CastExtensionsClient& operator=(const CastExtensionsClient&) = delete;
+
   ~CastExtensionsClient() override;
 
   // ExtensionsClient overrides:
@@ -42,8 +46,6 @@
 
   const GURL webstore_base_url_;
   const GURL webstore_update_url_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionsClient);
 };
 
 }  // namespace extensions
diff --git a/chromecast/common/cast_redirect_manifest_handler.h b/chromecast/common/cast_redirect_manifest_handler.h
index 17bb89b..a7290b1 100644
--- a/chromecast/common/cast_redirect_manifest_handler.h
+++ b/chromecast/common/cast_redirect_manifest_handler.h
@@ -19,6 +19,10 @@
 class CastRedirectHandler : public extensions::ManifestHandler {
  public:
   CastRedirectHandler();
+
+  CastRedirectHandler(const CastRedirectHandler&) = delete;
+  CastRedirectHandler& operator=(const CastRedirectHandler&) = delete;
+
   ~CastRedirectHandler() override;
 
   bool Parse(extensions::Extension* extension, std::u16string* error) override;
@@ -33,8 +37,6 @@
 
  private:
   base::span<const char* const> Keys() const override;
-
-  DISALLOW_COPY_AND_ASSIGN(CastRedirectHandler);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/common/cast_resource_delegate.h b/chromecast/common/cast_resource_delegate.h
index 47fafed3..4483c98 100644
--- a/chromecast/common/cast_resource_delegate.h
+++ b/chromecast/common/cast_resource_delegate.h
@@ -31,6 +31,10 @@
   static CastResourceDelegate* GetInstance();
 
   CastResourceDelegate();
+
+  CastResourceDelegate(const CastResourceDelegate&) = delete;
+  CastResourceDelegate& operator=(const CastResourceDelegate&) = delete;
+
   ~CastResourceDelegate() override;
 
   // ui:ResourceBundle::Delegate implementation:
@@ -61,8 +65,6 @@
   using ExtraLocaledStringMap = std::unordered_map<int, std::u16string>;
 
   ExtraLocaledStringMap extra_localized_strings_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastResourceDelegate);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/common/media/cast_media_drm_bridge_client.h b/chromecast/common/media/cast_media_drm_bridge_client.h
index 4f7d8e3..e7b57df2 100644
--- a/chromecast/common/media/cast_media_drm_bridge_client.h
+++ b/chromecast/common/media/cast_media_drm_bridge_client.h
@@ -17,6 +17,10 @@
 class CastMediaDrmBridgeClient : public ::media::MediaDrmBridgeClient {
  public:
   CastMediaDrmBridgeClient();
+
+  CastMediaDrmBridgeClient(const CastMediaDrmBridgeClient&) = delete;
+  CastMediaDrmBridgeClient& operator=(const CastMediaDrmBridgeClient&) = delete;
+
   ~CastMediaDrmBridgeClient() override;
 
  private:
@@ -30,8 +34,6 @@
 #endif  // BUILDFLAG(ENABLE_PLAYREADY)
 
   cdm::WidevineDrmDelegateAndroid widevine_delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastMediaDrmBridgeClient);
 };
 
 }  // namespace media
diff --git a/chromecast/crash/cast_crashdump_uploader.h b/chromecast/crash/cast_crashdump_uploader.h
index 9e1cd0ae..6a78a46 100644
--- a/chromecast/crash/cast_crashdump_uploader.h
+++ b/chromecast/crash/cast_crashdump_uploader.h
@@ -41,6 +41,10 @@
       const CastCrashdumpData& data,
       std::unique_ptr<google_breakpad::LibcurlWrapper> http_layer);
   explicit CastCrashdumpUploader(const CastCrashdumpData& data);
+
+  CastCrashdumpUploader(const CastCrashdumpUploader&) = delete;
+  CastCrashdumpUploader& operator=(const CastCrashdumpUploader&) = delete;
+
   virtual ~CastCrashdumpUploader();
 
   virtual bool AddAttachment(const std::string& label,
@@ -59,8 +63,6 @@
 
   // Holds the following mapping for HTTP request params: <key, value>
   std::map<std::string, std::string> parameters_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastCrashdumpUploader);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/crash/linux/dump_info.h b/chromecast/crash/linux/dump_info.h
index ebdfa69..1231c95 100644
--- a/chromecast/crash/linux/dump_info.h
+++ b/chromecast/crash/linux/dump_info.h
@@ -40,6 +40,9 @@
            const MinidumpParams& params,
            const std::vector<std::string>* attachments = nullptr);
 
+  DumpInfo(const DumpInfo&) = delete;
+  DumpInfo& operator=(const DumpInfo&) = delete;
+
   ~DumpInfo();
 
   const std::string& crashed_process_dump() const {
@@ -82,8 +85,6 @@
   base::Time dump_time_;
   MinidumpParams params_;
   bool valid_;
-
-  DISALLOW_COPY_AND_ASSIGN(DumpInfo);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/crash/linux/minidump_uploader.h b/chromecast/crash/linux/minidump_uploader.h
index 8f91aa3..84589ad0 100644
--- a/chromecast/crash/linux/minidump_uploader.h
+++ b/chromecast/crash/linux/minidump_uploader.h
@@ -31,6 +31,10 @@
                    const std::string& server_url,
                    CastCrashdumpUploader* const uploader,
                    PrefServiceGeneratorCallback callback);
+
+  MinidumpUploader(const MinidumpUploader&) = delete;
+  MinidumpUploader& operator=(const MinidumpUploader&) = delete;
+
   ~MinidumpUploader() override;
 
   // Attempts to upload all minidumps in the minidumps directory. Acquires a
@@ -65,8 +69,6 @@
   // Used for injecting mocks/inducing different behavior in unittests.
   CastCrashdumpUploader* const uploader_;
   PrefServiceGeneratorCallback pref_service_generator_;
-
-  DISALLOW_COPY_AND_ASSIGN(MinidumpUploader);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/crash/linux/minidump_writer.h b/chromecast/crash/linux/minidump_writer.h
index 813dc044..fe5d5fc 100644
--- a/chromecast/crash/linux/minidump_writer.h
+++ b/chromecast/crash/linux/minidump_writer.h
@@ -47,6 +47,9 @@
                  const MinidumpParams& params,
                  const std::vector<Attachment>* attachments = nullptr);
 
+  MinidumpWriter(const MinidumpWriter&) = delete;
+  MinidumpWriter& operator=(const MinidumpWriter&) = delete;
+
   ~MinidumpWriter() override;
 
   // Acquires exclusive access to the minidumps directory and generates a
@@ -69,8 +72,6 @@
   // integer otherwise. If a callback is not passed in the constructor, the
   // default implemementaion is used.
   DumpStateCallback dump_state_cb_;
-
-  DISALLOW_COPY_AND_ASSIGN(MinidumpWriter);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/crash/linux/synchronized_minidump_manager.h b/chromecast/crash/linux/synchronized_minidump_manager.h
index 26e6849..a0f2d7b0 100644
--- a/chromecast/crash/linux/synchronized_minidump_manager.h
+++ b/chromecast/crash/linux/synchronized_minidump_manager.h
@@ -49,6 +49,10 @@
   // Number of dumps allowed per period.
   static const int kRatelimitPeriodMaxDumps;
 
+  SynchronizedMinidumpManager(const SynchronizedMinidumpManager&) = delete;
+  SynchronizedMinidumpManager& operator=(const SynchronizedMinidumpManager&) =
+      delete;
+
   virtual ~SynchronizedMinidumpManager();
 
  protected:
@@ -143,8 +147,6 @@
   int lockfile_fd_;
   std::unique_ptr<base::Value> metadata_;
   std::unique_ptr<base::ListValue> dumps_;
-
-  DISALLOW_COPY_AND_ASSIGN(SynchronizedMinidumpManager);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/crypto/signature_cache.h b/chromecast/crypto/signature_cache.h
index b132b8e..31b8ba5f 100644
--- a/chromecast/crypto/signature_cache.h
+++ b/chromecast/crypto/signature_cache.h
@@ -21,6 +21,10 @@
 class SignatureCache {
  public:
   SignatureCache();
+
+  SignatureCache(const SignatureCache&) = delete;
+  SignatureCache& operator=(const SignatureCache&) = delete;
+
   ~SignatureCache();
 
   std::string Get(const std::string& wrapped_private_key,
@@ -34,8 +38,6 @@
   std::string key_;
   base::Lock lock_;
   base::HashingMRUCache<std::string, std::string> contents_;
-
-  DISALLOW_COPY_AND_ASSIGN(SignatureCache);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/device/bluetooth/le/ble_notification_logger.h b/chromecast/device/bluetooth/le/ble_notification_logger.h
index bb51b62..db098eb 100644
--- a/chromecast/device/bluetooth/le/ble_notification_logger.h
+++ b/chromecast/device/bluetooth/le/ble_notification_logger.h
@@ -23,6 +23,10 @@
   static constexpr auto kMinLogInterval = base::TimeDelta::FromMinutes(1);
 
   explicit BleNotificationLogger(GattClientManager* gcm);
+
+  BleNotificationLogger(const BleNotificationLogger&) = delete;
+  BleNotificationLogger& operator=(const BleNotificationLogger&) = delete;
+
   ~BleNotificationLogger() override;
 
   // GattClientManager::Observer implementation:
@@ -47,7 +51,6 @@
   // Key: Device address, Value: Map[Key: Characteristic UUID, Value: count]
   std::map<Addr, std::map<Uuid, int32_t>> device_to_char_uuid_to_count_;
   base::WeakPtrFactory<BleNotificationLogger> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(BleNotificationLogger);
 };
 
 }  // namespace bluetooth
diff --git a/chromecast/device/bluetooth/le/gatt_client_manager.h b/chromecast/device/bluetooth/le/gatt_client_manager.h
index ac404e98..fcfd05b 100644
--- a/chromecast/device/bluetooth/le/gatt_client_manager.h
+++ b/chromecast/device/bluetooth/le/gatt_client_manager.h
@@ -71,6 +71,9 @@
       BluetoothManagerPlatform* bluetooth_manager,
       LeScanManager* le_scan_manager);
 
+  GattClientManager(const GattClientManager&) = delete;
+  GattClientManager& operator=(const GattClientManager&) = delete;
+
   virtual ~GattClientManager() = default;
 
   virtual void Initialize(
@@ -130,9 +133,6 @@
 
  protected:
   GattClientManager() = default;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GattClientManager);
 };
 
 }  // namespace bluetooth
diff --git a/chromecast/device/bluetooth/le/gatt_client_manager_impl.h b/chromecast/device/bluetooth/le/gatt_client_manager_impl.h
index 4a366154..ff464e4 100644
--- a/chromecast/device/bluetooth/le/gatt_client_manager_impl.h
+++ b/chromecast/device/bluetooth/le/gatt_client_manager_impl.h
@@ -42,6 +42,10 @@
       base::TimeDelta::FromSeconds(10);
 
   explicit GattClientManagerImpl(bluetooth_v2_shlib::GattClient* gatt_client);
+
+  GattClientManagerImpl(const GattClientManagerImpl&) = delete;
+  GattClientManagerImpl& operator=(const GattClientManagerImpl&) = delete;
+
   ~GattClientManagerImpl() override;
 
   void InitializeOnIoThread();
@@ -192,7 +196,6 @@
 
   base::WeakPtr<GattClientManagerImpl> weak_this_;
   std::unique_ptr<base::WeakPtrFactory<GattClientManagerImpl>> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(GattClientManagerImpl);
 };
 
 }  // namespace bluetooth
diff --git a/chromecast/device/bluetooth/le/le_scan_manager.h b/chromecast/device/bluetooth/le/le_scan_manager.h
index 31b1a44..12c4fb0e 100644
--- a/chromecast/device/bluetooth/le/le_scan_manager.h
+++ b/chromecast/device/bluetooth/le/le_scan_manager.h
@@ -47,13 +47,13 @@
 
   class ScanHandle {
    public:
+    ScanHandle(const ScanHandle&) = delete;
+    ScanHandle& operator=(const ScanHandle&) = delete;
+
     virtual ~ScanHandle() = default;
 
    protected:
     ScanHandle() = default;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(ScanHandle);
   };
 
   static std::unique_ptr<LeScanManager> Create(
diff --git a/chromecast/device/bluetooth/le/le_scan_manager_impl.h b/chromecast/device/bluetooth/le/le_scan_manager_impl.h
index 8856adb..2a0080b3 100644
--- a/chromecast/device/bluetooth/le/le_scan_manager_impl.h
+++ b/chromecast/device/bluetooth/le/le_scan_manager_impl.h
@@ -26,6 +26,10 @@
                           public bluetooth_v2_shlib::LeScanner::Delegate {
  public:
   explicit LeScanManagerImpl(bluetooth_v2_shlib::LeScannerImpl* le_scanner);
+
+  LeScanManagerImpl(const LeScanManagerImpl&) = delete;
+  LeScanManagerImpl& operator=(const LeScanManagerImpl&) = delete;
+
   ~LeScanManagerImpl() override;
 
   static constexpr int kMaxScanResultEntries = 1024;
@@ -76,8 +80,6 @@
   std::set<int32_t> scan_handle_ids_;
 
   base::WeakPtrFactory<LeScanManagerImpl> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(LeScanManagerImpl);
 };
 
 }  // namespace bluetooth
diff --git a/chromecast/external_mojo/broker_service/broker_service.h b/chromecast/external_mojo/broker_service/broker_service.h
index 309d8f40..588d70b 100644
--- a/chromecast/external_mojo/broker_service/broker_service.h
+++ b/chromecast/external_mojo/broker_service/broker_service.h
@@ -56,6 +56,10 @@
   static const service_manager::Manifest& GetManifest();
 
   explicit BrokerService(service_manager::Connector* connector);
+
+  BrokerService(const BrokerService&) = delete;
+  BrokerService& operator=(const BrokerService&) = delete;
+
   ~BrokerService() override;
 
   // ::service_manager::Service implementation:
@@ -81,8 +85,6 @@
   InterfaceBundle bundle_;
 
   base::SequenceBound<ExternalMojoBroker> broker_;
-
-  DISALLOW_COPY_AND_ASSIGN(BrokerService);
 };
 
 }  // namespace external_mojo
diff --git a/chromecast/external_mojo/external_service_support/chromium_service.h b/chromecast/external_mojo/external_service_support/chromium_service.h
index f527c875..5c4de89 100644
--- a/chromecast/external_mojo/external_service_support/chromium_service.h
+++ b/chromecast/external_mojo/external_service_support/chromium_service.h
@@ -36,6 +36,10 @@
       mojo::Remote<service_manager::mojom::Service> service_remote,
       std::unique_ptr<service_manager::Service> chromium_service,
       const std::string& service_name);
+
+  ChromiumServiceWrapper(const ChromiumServiceWrapper&) = delete;
+  ChromiumServiceWrapper& operator=(const ChromiumServiceWrapper&) = delete;
+
   ~ChromiumServiceWrapper() override;
 
  private:
@@ -47,8 +51,6 @@
   const std::unique_ptr<service_manager::Service> chromium_service_;
 
   mojo::Receiver<external_mojo::mojom::ExternalService> service_receiver_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(ChromiumServiceWrapper);
 };
 
 // Creates a ServiceRequest (analogous to one created by Chromium
diff --git a/chromecast/external_mojo/external_service_support/external_connector_impl.h b/chromecast/external_mojo/external_service_support/external_connector_impl.h
index 696f3fef..5b7bbf3 100644
--- a/chromecast/external_mojo/external_service_support/external_connector_impl.h
+++ b/chromecast/external_mojo/external_service_support/external_connector_impl.h
@@ -32,6 +32,10 @@
   explicit ExternalConnectorImpl(
       mojo::PendingRemote<external_mojo::mojom::ExternalConnector>
           pending_remote);
+
+  ExternalConnectorImpl(const ExternalConnectorImpl&) = delete;
+  ExternalConnectorImpl& operator=(const ExternalConnectorImpl&) = delete;
+
   ~ExternalConnectorImpl() override;
 
   // ExternalConnector implementation:
@@ -80,8 +84,6 @@
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::WeakPtrFactory<ExternalConnectorImpl> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(ExternalConnectorImpl);
 };
 
 }  // namespace external_service_support
diff --git a/chromecast/external_mojo/external_service_support/external_service.h b/chromecast/external_mojo/external_service_support/external_service.h
index 7877f90..4672c0f 100644
--- a/chromecast/external_mojo/external_service_support/external_service.h
+++ b/chromecast/external_mojo/external_service_support/external_service.h
@@ -26,6 +26,10 @@
 class ExternalService : public external_mojo::mojom::ExternalService {
  public:
   ExternalService();
+
+  ExternalService(const ExternalService&) = delete;
+  ExternalService& operator=(const ExternalService&) = delete;
+
   ~ExternalService() override;
 
   // Returns the Mojo receiver for this service.
@@ -71,8 +75,6 @@
   mojo::Receiver<external_mojo::mojom::ExternalService> service_receiver_{this};
 
   SEQUENCE_CHECKER(sequence_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(ExternalService);
 };
 
 }  // namespace external_service_support
diff --git a/chromecast/external_mojo/public/cpp/external_mojo_broker.h b/chromecast/external_mojo/public/cpp/external_mojo_broker.h
index 7d308f27..d9f5cb72 100644
--- a/chromecast/external_mojo/public/cpp/external_mojo_broker.h
+++ b/chromecast/external_mojo/public/cpp/external_mojo_broker.h
@@ -27,6 +27,9 @@
  public:
   explicit ExternalMojoBroker(const std::string& broker_path);
 
+  ExternalMojoBroker(const ExternalMojoBroker&) = delete;
+  ExternalMojoBroker& operator=(const ExternalMojoBroker&) = delete;
+
   ~ExternalMojoBroker();
 
   // Initializes the embedded into a Chromium process (eg in cast_shell).
@@ -47,8 +50,6 @@
 
   std::unique_ptr<ConnectorImpl> connector_;
   std::unique_ptr<ReadWatcher> read_watcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExternalMojoBroker);
 };
 
 }  // namespace external_mojo
diff --git a/chromecast/fuchsia/queryable_data_host_fuchsia.h b/chromecast/fuchsia/queryable_data_host_fuchsia.h
index beb1749..64e14f8 100644
--- a/chromecast/fuchsia/queryable_data_host_fuchsia.h
+++ b/chromecast/fuchsia/queryable_data_host_fuchsia.h
@@ -17,14 +17,15 @@
 class QueryableDataHostFuchsia : public QueryableDataHost {
  public:
   QueryableDataHostFuchsia();
+
+  QueryableDataHostFuchsia(const QueryableDataHostFuchsia&) = delete;
+  QueryableDataHostFuchsia& operator=(const QueryableDataHostFuchsia&) = delete;
+
   ~QueryableDataHostFuchsia() override;
 
   // chromecast::QueryableDataHost implementation:
   void SendQueryableValue(const std::string& key,
                           const base::Value& value) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(QueryableDataHostFuchsia);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/gpu/cast_content_gpu_client.h b/chromecast/gpu/cast_content_gpu_client.h
index 8af1f7f..5b6d61b 100644
--- a/chromecast/gpu/cast_content_gpu_client.h
+++ b/chromecast/gpu/cast_content_gpu_client.h
@@ -16,6 +16,9 @@
  public:
   static std::unique_ptr<CastContentGpuClient> Create();
 
+  CastContentGpuClient(const CastContentGpuClient&) = delete;
+  CastContentGpuClient& operator=(const CastContentGpuClient&) = delete;
+
   ~CastContentGpuClient() override;
 
   // content::ContentGpuClient:
@@ -24,9 +27,6 @@
 
  protected:
   CastContentGpuClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastContentGpuClient);
 };
 
 }  // namespace shell
diff --git a/chromecast/graphics/accessibility/accessibility_cursor_ring_layer.h b/chromecast/graphics/accessibility/accessibility_cursor_ring_layer.h
index 299f13b..fc81fc9 100644
--- a/chromecast/graphics/accessibility/accessibility_cursor_ring_layer.h
+++ b/chromecast/graphics/accessibility/accessibility_cursor_ring_layer.h
@@ -22,6 +22,11 @@
                                int red,
                                int green,
                                int blue);
+
+  AccessibilityCursorRingLayer(const AccessibilityCursorRingLayer&) = delete;
+  AccessibilityCursorRingLayer& operator=(const AccessibilityCursorRingLayer&) =
+      delete;
+
   ~AccessibilityCursorRingLayer() override;
 
   // Create the layer and update its bounds and position in the hierarchy.
@@ -37,8 +42,6 @@
   int red_;
   int green_;
   int blue_;
-
-  DISALLOW_COPY_AND_ASSIGN(AccessibilityCursorRingLayer);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/accessibility_focus_ring_controller.h b/chromecast/graphics/accessibility/accessibility_focus_ring_controller.h
index 2504c524..91e1c88 100644
--- a/chromecast/graphics/accessibility/accessibility_focus_ring_controller.h
+++ b/chromecast/graphics/accessibility/accessibility_focus_ring_controller.h
@@ -35,6 +35,12 @@
 class AccessibilityFocusRingController : public AccessibilityLayerDelegate {
  public:
   explicit AccessibilityFocusRingController(aura::Window* root_window);
+
+  AccessibilityFocusRingController(const AccessibilityFocusRingController&) =
+      delete;
+  AccessibilityFocusRingController& operator=(
+      const AccessibilityFocusRingController&) = delete;
+
   ~AccessibilityFocusRingController() override;
 
   void SetFocusRingColor(SkColor color);
@@ -128,8 +134,6 @@
   std::unique_ptr<AccessibilityHighlightLayer> highlight_layer_;
   SkColor highlight_color_ = SK_ColorBLACK;
   float highlight_opacity_ = 0.f;
-
-  DISALLOW_COPY_AND_ASSIGN(AccessibilityFocusRingController);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/accessibility_focus_ring_controller_unittest.cc b/chromecast/graphics/accessibility/accessibility_focus_ring_controller_unittest.cc
index 10c25838..b268338 100644
--- a/chromecast/graphics/accessibility/accessibility_focus_ring_controller_unittest.cc
+++ b/chromecast/graphics/accessibility/accessibility_focus_ring_controller_unittest.cc
@@ -22,6 +22,10 @@
 class CastTestWindowDelegate : public aura::test::TestWindowDelegate {
  public:
   CastTestWindowDelegate() : key_code_(ui::VKEY_UNKNOWN) {}
+
+  CastTestWindowDelegate(const CastTestWindowDelegate&) = delete;
+  CastTestWindowDelegate& operator=(const CastTestWindowDelegate&) = delete;
+
   ~CastTestWindowDelegate() override {}
 
   // Overridden from TestWindowDelegate:
@@ -33,8 +37,6 @@
 
  private:
   ui::KeyboardCode key_code_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastTestWindowDelegate);
 };
 
 class TestableAccessibilityFocusRingController
diff --git a/chromecast/graphics/accessibility/accessibility_focus_ring_layer.h b/chromecast/graphics/accessibility/accessibility_focus_ring_layer.h
index 44c0142c..cc07f36 100644
--- a/chromecast/graphics/accessibility/accessibility_focus_ring_layer.h
+++ b/chromecast/graphics/accessibility/accessibility_focus_ring_layer.h
@@ -22,6 +22,11 @@
  public:
   AccessibilityFocusRingLayer(aura::Window* root_window,
                               AccessibilityLayerDelegate* delegate);
+
+  AccessibilityFocusRingLayer(const AccessibilityFocusRingLayer&) = delete;
+  AccessibilityFocusRingLayer& operator=(const AccessibilityFocusRingLayer&) =
+      delete;
+
   ~AccessibilityFocusRingLayer() override;
 
   // Create the layer and update its bounds and position in the hierarchy.
@@ -33,8 +38,6 @@
 
   // The outline of the current focus ring.
   AccessibilityFocusRing ring_;
-
-  DISALLOW_COPY_AND_ASSIGN(AccessibilityFocusRingLayer);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/accessibility_highlight_layer.h b/chromecast/graphics/accessibility/accessibility_highlight_layer.h
index a3d4b53..626f066 100644
--- a/chromecast/graphics/accessibility/accessibility_highlight_layer.h
+++ b/chromecast/graphics/accessibility/accessibility_highlight_layer.h
@@ -23,6 +23,11 @@
  public:
   explicit AccessibilityHighlightLayer(aura::Window* root_window,
                                        AccessibilityLayerDelegate* delegate);
+
+  AccessibilityHighlightLayer(const AccessibilityHighlightLayer&) = delete;
+  AccessibilityHighlightLayer& operator=(const AccessibilityHighlightLayer&) =
+      delete;
+
   ~AccessibilityHighlightLayer() override;
 
   // Create the layer and update its bounds and position in the hierarchy.
@@ -41,8 +46,6 @@
 
   // The highlight color.
   SkColor highlight_color_;
-
-  DISALLOW_COPY_AND_ASSIGN(AccessibilityHighlightLayer);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/accessibility_layer.h b/chromecast/graphics/accessibility/accessibility_layer.h
index 98ba5ae..3a51182e 100644
--- a/chromecast/graphics/accessibility/accessibility_layer.h
+++ b/chromecast/graphics/accessibility/accessibility_layer.h
@@ -45,6 +45,10 @@
  public:
   AccessibilityLayer(aura::Window* root_window,
                      AccessibilityLayerDelegate* delegate);
+
+  AccessibilityLayer(const AccessibilityLayer&) = delete;
+  AccessibilityLayer& operator=(const AccessibilityLayer&) = delete;
+
   ~AccessibilityLayer() override;
 
   // Move the accessibility layer to the given bounds in the coordinates of
@@ -96,8 +100,6 @@
 
   // The object that owns this layer.
   AccessibilityLayerDelegate* delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(AccessibilityLayer);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/focus_ring_controller.h b/chromecast/graphics/accessibility/focus_ring_controller.h
index cae253e4..bbbf0ad 100644
--- a/chromecast/graphics/accessibility/focus_ring_controller.h
+++ b/chromecast/graphics/accessibility/focus_ring_controller.h
@@ -37,6 +37,10 @@
  public:
   explicit FocusRingController(aura::Window* root_window,
                                wm::ActivationClient* activation_client);
+
+  FocusRingController(const FocusRingController&) = delete;
+  FocusRingController& operator=(const FocusRingController&) = delete;
+
   ~FocusRingController() override;
 
   // Turns on/off the focus ring.
@@ -74,8 +78,6 @@
   bool visible_;
   views::Widget* widget_;
   std::unique_ptr<FocusRingLayer> focus_ring_layer_;
-
-  DISALLOW_COPY_AND_ASSIGN(FocusRingController);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/focus_ring_layer.h b/chromecast/graphics/accessibility/focus_ring_layer.h
index 6e1521a..3cf8b56 100644
--- a/chromecast/graphics/accessibility/focus_ring_layer.h
+++ b/chromecast/graphics/accessibility/focus_ring_layer.h
@@ -23,6 +23,10 @@
  public:
   explicit FocusRingLayer(aura::Window* root_window,
                           AccessibilityLayerDelegate* delegate);
+
+  FocusRingLayer(const FocusRingLayer&) = delete;
+  FocusRingLayer& operator=(const FocusRingLayer&) = delete;
+
   ~FocusRingLayer() override;
 
   // AccessibilityLayer overrides:
@@ -42,8 +46,6 @@
   void OnPaintLayer(const ui::PaintContext& context) override;
 
   absl::optional<SkColor> custom_color_;
-
-  DISALLOW_COPY_AND_ASSIGN(FocusRingLayer);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc b/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc
index 27a5edc..fc04e7f4 100644
--- a/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc
+++ b/chromecast/graphics/accessibility/fullscreen_magnification_controller.cc
@@ -67,6 +67,10 @@
     : public ui::GestureProviderAuraClient {
  public:
   GestureProviderClient() = default;
+
+  GestureProviderClient(const GestureProviderClient&) = delete;
+  GestureProviderClient& operator=(const GestureProviderClient&) = delete;
+
   ~GestureProviderClient() override = default;
 
   // ui::GestureProviderAuraClient overrides:
@@ -82,9 +86,6 @@
     DCHECK_NE(ui::ET_GESTURE_PINCH_END, event->type());
     DCHECK_NE(ui::ET_GESTURE_PINCH_UPDATE, event->type());
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GestureProviderClient);
 };
 
 FullscreenMagnificationController::FullscreenMagnificationController(
diff --git a/chromecast/graphics/accessibility/partial_magnification_controller.cc b/chromecast/graphics/accessibility/partial_magnification_controller.cc
index a8c0ab6..4c77f045 100644
--- a/chromecast/graphics/accessibility/partial_magnification_controller.cc
+++ b/chromecast/graphics/accessibility/partial_magnification_controller.cc
@@ -85,6 +85,9 @@
     layer_.SetBounds(gfx::Rect(mask_bounds));
   }
 
+  ContentMask(const ContentMask&) = delete;
+  ContentMask& operator=(const ContentMask&) = delete;
+
   ~ContentMask() override { layer_.set_delegate(nullptr); }
 
   ui::Layer* layer() { return &layer_; }
@@ -122,7 +125,6 @@
 
   ui::Layer layer_;
   bool is_border_;
-  DISALLOW_COPY_AND_ASSIGN(ContentMask);
 };
 
 // The border renderer draws the border as well as outline on both the outer and
@@ -139,6 +141,9 @@
         gfx::Vector2d(0, 0), kShadowThickness, kTopShadowColor));
   }
 
+  BorderRenderer(const BorderRenderer&) = delete;
+  BorderRenderer& operator=(const BorderRenderer&) = delete;
+
   ~BorderRenderer() override = default;
 
  private:
@@ -188,8 +193,6 @@
 
   gfx::Rect magnifier_window_bounds_;
   std::vector<gfx::ShadowValue> magnifier_shadows_;
-
-  DISALLOW_COPY_AND_ASSIGN(BorderRenderer);
 };
 
 PartialMagnificationController::PartialMagnificationController(
diff --git a/chromecast/graphics/accessibility/partial_magnification_controller.h b/chromecast/graphics/accessibility/partial_magnification_controller.h
index 356e7ea..b50b9e3 100644
--- a/chromecast/graphics/accessibility/partial_magnification_controller.h
+++ b/chromecast/graphics/accessibility/partial_magnification_controller.h
@@ -30,6 +30,12 @@
                                        public views::WidgetObserver {
  public:
   explicit PartialMagnificationController(aura::Window* root_window);
+
+  PartialMagnificationController(const PartialMagnificationController&) =
+      delete;
+  PartialMagnificationController& operator=(
+      const PartialMagnificationController&) = delete;
+
   ~PartialMagnificationController() override;
 
   // Turns the partial screen magnifier feature on or off.
@@ -98,8 +104,6 @@
   // Masks the content of |border_layer_| so that only a circle outline is
   // drawn.
   std::unique_ptr<ContentMask> border_mask_;
-
-  DISALLOW_COPY_AND_ASSIGN(PartialMagnificationController);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc b/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc
index c9c1b58..992ea63 100644
--- a/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc
+++ b/chromecast/graphics/accessibility/partial_magnification_controller_unittest.cc
@@ -14,6 +14,10 @@
 class CastTestWindowDelegate : public aura::test::TestWindowDelegate {
  public:
   CastTestWindowDelegate() : key_code_(ui::VKEY_UNKNOWN) {}
+
+  CastTestWindowDelegate(const CastTestWindowDelegate&) = delete;
+  CastTestWindowDelegate& operator=(const CastTestWindowDelegate&) = delete;
+
   ~CastTestWindowDelegate() override {}
 
   // Overridden from TestWindowDelegate:
@@ -25,8 +29,6 @@
 
  private:
   ui::KeyboardCode key_code_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastTestWindowDelegate);
 };
 
 // Wrapper for PartialMagnificationController that exposes internal state to
@@ -56,6 +58,12 @@
 class PartialMagnificationControllerTest : public views::ViewsTestBase {
  public:
   PartialMagnificationControllerTest() = default;
+
+  PartialMagnificationControllerTest(
+      const PartialMagnificationControllerTest&) = delete;
+  PartialMagnificationControllerTest& operator=(
+      const PartialMagnificationControllerTest&) = delete;
+
   ~PartialMagnificationControllerTest() override = default;
 
   void SetUp() override {
@@ -95,8 +103,6 @@
 
   CastTestWindowDelegate test_window_delegate_;
   std::unique_ptr<PartialMagnificationController> controller_;
-
-  DISALLOW_COPY_AND_ASSIGN(PartialMagnificationControllerTest);
 };
 
 // The magnifier should not show up immediately after being enabled.
diff --git a/chromecast/graphics/cast_focus_client_aura.h b/chromecast/graphics/cast_focus_client_aura.h
index ec4f8d6..3e19740c 100644
--- a/chromecast/graphics/cast_focus_client_aura.h
+++ b/chromecast/graphics/cast_focus_client_aura.h
@@ -25,6 +25,10 @@
                             public wm::ActivationClient {
  public:
   CastFocusClientAura();
+
+  CastFocusClientAura(const CastFocusClientAura&) = delete;
+  CastFocusClientAura& operator=(const CastFocusClientAura&) = delete;
+
   ~CastFocusClientAura() override;
 
   // aura::client::FocusClient implementation:
@@ -74,8 +78,6 @@
   // focus to them.  We assume that this is a small list so that we can perform
   // linear ops on it.
   std::vector<aura::Window*> focusable_windows_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastFocusClientAura);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/cast_screen.h b/chromecast/graphics/cast_screen.h
index 4d26107..b25ab62 100644
--- a/chromecast/graphics/cast_screen.h
+++ b/chromecast/graphics/cast_screen.h
@@ -24,6 +24,10 @@
 class CastScreen : public display::ScreenBase {
  public:
   CastScreen();
+
+  CastScreen(const CastScreen&) = delete;
+  CastScreen& operator=(const CastScreen&) = delete;
+
   ~CastScreen() override;
 
   // display::Screen overrides:
@@ -52,8 +56,6 @@
 
  private:
   absl::optional<display::Display> stashed_display_settings_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastScreen);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/cast_window_manager_aura.cc b/chromecast/graphics/cast_window_manager_aura.cc
index 1ab0d96..9772ce8 100644
--- a/chromecast/graphics/cast_window_manager_aura.cc
+++ b/chromecast/graphics/cast_window_manager_aura.cc
@@ -67,6 +67,10 @@
  public:
   CastLayoutManager(CastWindowManagerAura* window_manager,
                     aura::Window* parent);
+
+  CastLayoutManager(const CastLayoutManager&) = delete;
+  CastLayoutManager& operator=(const CastLayoutManager&) = delete;
+
   ~CastLayoutManager() override;
 
  private:
@@ -85,8 +89,6 @@
 
   CastWindowManagerAura* const window_manager_;
   aura::Window* const parent_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastLayoutManager);
 };
 
 CastLayoutManager::CastLayoutManager(CastWindowManagerAura* window_manager,
diff --git a/chromecast/graphics/cast_window_manager_aura.h b/chromecast/graphics/cast_window_manager_aura.h
index 240c36e..97d680a 100644
--- a/chromecast/graphics/cast_window_manager_aura.h
+++ b/chromecast/graphics/cast_window_manager_aura.h
@@ -35,6 +35,10 @@
                               public aura::client::WindowParentingClient {
  public:
   explicit CastWindowManagerAura(bool enable_input);
+
+  CastWindowManagerAura(const CastWindowManagerAura&) = delete;
+  CastWindowManagerAura& operator=(const CastWindowManagerAura&) = delete;
+
   ~CastWindowManagerAura() override;
 
   void Setup();
@@ -86,8 +90,6 @@
 
   std::vector<WindowId> window_order_;
   base::ObserverList<Observer>::Unchecked observer_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastWindowManagerAura);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/cast_window_manager_aura_test.cc b/chromecast/graphics/cast_window_manager_aura_test.cc
index e33b5d27..9e27123b 100644
--- a/chromecast/graphics/cast_window_manager_aura_test.cc
+++ b/chromecast/graphics/cast_window_manager_aura_test.cc
@@ -21,6 +21,10 @@
 class CastTestWindowDelegate : public aura::test::TestWindowDelegate {
  public:
   CastTestWindowDelegate() : key_code_(ui::VKEY_UNKNOWN) {}
+
+  CastTestWindowDelegate(const CastTestWindowDelegate&) = delete;
+  CastTestWindowDelegate& operator=(const CastTestWindowDelegate&) = delete;
+
   ~CastTestWindowDelegate() override {}
 
   // Overridden from TestWindowDelegate:
@@ -32,8 +36,6 @@
 
  private:
   ui::KeyboardCode key_code_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastTestWindowDelegate);
 };
 
 class TestWindow {
diff --git a/chromecast/graphics/cast_window_manager_default.h b/chromecast/graphics/cast_window_manager_default.h
index 0be6003..2f6a0a4 100644
--- a/chromecast/graphics/cast_window_manager_default.h
+++ b/chromecast/graphics/cast_window_manager_default.h
@@ -15,6 +15,10 @@
 class CastWindowManagerDefault : public CastWindowManager {
  public:
   CastWindowManagerDefault();
+
+  CastWindowManagerDefault(const CastWindowManagerDefault&) = delete;
+  CastWindowManagerDefault& operator=(const CastWindowManagerDefault&) = delete;
+
   ~CastWindowManagerDefault() override;
 
   // CastWindowManager implementation:
@@ -37,9 +41,6 @@
       CastTouchActivityObserver* observer) override;
   void SetEnableRoundedCorners(bool enable) override;
   void NotifyColorInversionEnabled(bool enabled) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastWindowManagerDefault);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/cast_window_tree_host_aura.h b/chromecast/graphics/cast_window_tree_host_aura.h
index 3a70362..b2dbf45 100644
--- a/chromecast/graphics/cast_window_tree_host_aura.h
+++ b/chromecast/graphics/cast_window_tree_host_aura.h
@@ -14,6 +14,10 @@
  public:
   CastWindowTreeHostAura(bool enable_input,
                          ui::PlatformWindowInitProperties properties);
+
+  CastWindowTreeHostAura(const CastWindowTreeHostAura&) = delete;
+  CastWindowTreeHostAura& operator=(const CastWindowTreeHostAura&) = delete;
+
   ~CastWindowTreeHostAura() override;
 
   // aura::WindowTreeHostPlatform implementation:
@@ -25,8 +29,6 @@
 
  private:
   const bool enable_input_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastWindowTreeHostAura);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/gestures/cast_gesture_handler.h b/chromecast/graphics/gestures/cast_gesture_handler.h
index 0b61ffa..22fde1a 100644
--- a/chromecast/graphics/gestures/cast_gesture_handler.h
+++ b/chromecast/graphics/gestures/cast_gesture_handler.h
@@ -40,6 +40,10 @@
   };
 
   CastGestureHandler() = default;
+
+  CastGestureHandler(const CastGestureHandler&) = delete;
+  CastGestureHandler& operator=(const CastGestureHandler&) = delete;
+
   virtual ~CastGestureHandler() = default;
 
   // Returns the gesture handler's current priority.
@@ -60,9 +64,6 @@
   // Triggered on the completion of a tap event, fire after a press
   // followed by a release, within the tap timeout window
   virtual void HandleTapGesture(const gfx::Point& touch_location) = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastGestureHandler);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/gestures/cast_system_gesture_event_handler.h b/chromecast/graphics/gestures/cast_system_gesture_event_handler.h
index 33b58d10..439d937 100644
--- a/chromecast/graphics/gestures/cast_system_gesture_event_handler.h
+++ b/chromecast/graphics/gestures/cast_system_gesture_event_handler.h
@@ -23,6 +23,10 @@
       CastSystemGestureDispatcher* dispatcher,
       aura::Window* root_window);
 
+  CastSystemGestureEventHandler(const CastSystemGestureEventHandler&) = delete;
+  CastSystemGestureEventHandler& operator=(
+      const CastSystemGestureEventHandler&) = delete;
+
   ~CastSystemGestureEventHandler() override;
 
   // ui::EventHandler implementation.
@@ -32,8 +36,6 @@
  private:
   CastSystemGestureDispatcher* dispatcher_;
   aura::Window* root_window_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastSystemGestureEventHandler);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/gestures/multiple_tap_detector.h b/chromecast/graphics/gestures/multiple_tap_detector.h
index 585db944..972501e 100644
--- a/chromecast/graphics/gestures/multiple_tap_detector.h
+++ b/chromecast/graphics/gestures/multiple_tap_detector.h
@@ -46,6 +46,10 @@
  public:
   MultipleTapDetector(aura::Window* root_window,
                       MultipleTapDetectorDelegate* delegate);
+
+  MultipleTapDetector(const MultipleTapDetector&) = delete;
+  MultipleTapDetector& operator=(const MultipleTapDetector&) = delete;
+
   ~MultipleTapDetector() override;
 
   void set_enabled(bool enabled) { enabled_ = enabled; }
@@ -88,8 +92,6 @@
     const Continuation continuation;
   };
   std::deque<Stash> stashed_events_;
-
-  DISALLOW_COPY_AND_ASSIGN(MultipleTapDetector);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/gestures/side_swipe_detector.h b/chromecast/graphics/gestures/side_swipe_detector.h
index 0222f2ce..9571447 100644
--- a/chromecast/graphics/gestures/side_swipe_detector.h
+++ b/chromecast/graphics/gestures/side_swipe_detector.h
@@ -28,6 +28,9 @@
   SideSwipeDetector(CastGestureHandler* gesture_handler,
                     aura::Window* root_window);
 
+  SideSwipeDetector(const SideSwipeDetector&) = delete;
+  SideSwipeDetector& operator=(const SideSwipeDetector&) = delete;
+
   ~SideSwipeDetector() override;
 
   CastSideSwipeOrigin GetDragPosition(const gfx::Point& point,
@@ -52,8 +55,6 @@
   base::ElapsedTimer current_swipe_time_;
 
   std::deque<ui::TouchEvent> stashed_events_;
-
-  DISALLOW_COPY_AND_ASSIGN(SideSwipeDetector);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/graphics/rounded_window_corners_aura.cc b/chromecast/graphics/rounded_window_corners_aura.cc
index efcfd9ad..12152b1a 100644
--- a/chromecast/graphics/rounded_window_corners_aura.cc
+++ b/chromecast/graphics/rounded_window_corners_aura.cc
@@ -74,6 +74,10 @@
 class RoundedWindowCornersAura : public RoundedWindowCorners {
  public:
   explicit RoundedWindowCornersAura(CastWindowManager* window_manager);
+
+  RoundedWindowCornersAura(const RoundedWindowCornersAura&) = delete;
+  RoundedWindowCornersAura& operator=(const RoundedWindowCornersAura&) = delete;
+
   ~RoundedWindowCornersAura() override;
 
   void SetEnabled(bool enable) override;
@@ -87,8 +91,6 @@
   std::vector<BlackCornerView*> corners_;
 
   THREAD_CHECKER(thread_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(RoundedWindowCornersAura);
 };
 
 RoundedWindowCornersAura::RoundedWindowCornersAura(
diff --git a/chromecast/graphics/rounded_window_corners_default.cc b/chromecast/graphics/rounded_window_corners_default.cc
index 399304b1..2f2ad6d 100644
--- a/chromecast/graphics/rounded_window_corners_default.cc
+++ b/chromecast/graphics/rounded_window_corners_default.cc
@@ -14,14 +14,16 @@
 class RoundedWindowCornersDefault : public RoundedWindowCorners {
  public:
   RoundedWindowCornersDefault() {}
+
+  RoundedWindowCornersDefault(const RoundedWindowCornersDefault&) = delete;
+  RoundedWindowCornersDefault& operator=(const RoundedWindowCornersDefault&) =
+      delete;
+
   ~RoundedWindowCornersDefault() override {}
 
   void SetEnabled(bool enable) override {}
   bool IsEnabled() const override { return false; }
   void SetColorInversion(bool enable) override {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(RoundedWindowCornersDefault);
 };
 
 }  // namespace
diff --git a/chromecast/media/audio/audio_fader.h b/chromecast/media/audio/audio_fader.h
index bad614f..411387d 100644
--- a/chromecast/media/audio/audio_fader.h
+++ b/chromecast/media/audio/audio_fader.h
@@ -28,6 +28,10 @@
              base::TimeDelta fade_time,
              double playback_rate);
   AudioFader(AudioProvider* provider, int fade_frames, double playback_rate);
+
+  AudioFader(const AudioFader&) = delete;
+  AudioFader& operator=(const AudioFader&) = delete;
+
   ~AudioFader() override;
 
   int buffered_frames() const { return buffered_frames_; }
@@ -91,8 +95,6 @@
   std::unique_ptr<CastAudioBus> fade_buffer_;
   int buffered_frames_ = 0;
   int fade_frames_remaining_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioFader);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/audio_io_thread.h b/chromecast/media/audio/audio_io_thread.h
index 762c612..7c9dc20 100644
--- a/chromecast/media/audio/audio_io_thread.h
+++ b/chromecast/media/audio/audio_io_thread.h
@@ -21,6 +21,10 @@
   static AudioIoThread* Get();
 
   AudioIoThread();
+
+  AudioIoThread(const AudioIoThread&) = delete;
+  AudioIoThread& operator=(const AudioIoThread&) = delete;
+
   ~AudioIoThread();
 
   scoped_refptr<base::SequencedTaskRunner> task_runner() const {
@@ -29,8 +33,6 @@
 
  private:
   base::Thread thread_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioIoThread);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/media/audio/cast_audio_device_factory.h b/chromecast/media/audio/cast_audio_device_factory.h
index 6276e453d..7390888 100644
--- a/chromecast/media/audio/cast_audio_device_factory.h
+++ b/chromecast/media/audio/cast_audio_device_factory.h
@@ -25,6 +25,10 @@
 class CastAudioDeviceFactory final : public blink::WebAudioDeviceFactory {
  public:
   CastAudioDeviceFactory();
+
+  CastAudioDeviceFactory(const CastAudioDeviceFactory&) = delete;
+  CastAudioDeviceFactory& operator=(const CastAudioDeviceFactory&) = delete;
+
   ~CastAudioDeviceFactory() override;
 
   scoped_refptr<::media::AudioRendererSink> CreateFinalAudioRendererSink(
@@ -46,9 +50,6 @@
   scoped_refptr<::media::AudioCapturerSource> CreateAudioCapturerSource(
       const blink::LocalFrameToken& frame_token,
       const ::media::AudioSourceParameters& params) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CastAudioDeviceFactory);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/cast_audio_manager.h b/chromecast/media/audio/cast_audio_manager.h
index a8a0f7d..74e83e4 100644
--- a/chromecast/media/audio/cast_audio_manager.h
+++ b/chromecast/media/audio/cast_audio_manager.h
@@ -57,6 +57,10 @@
       scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
       external_service_support::ExternalConnector* connector,
       bool use_mixer);
+
+  CastAudioManager(const CastAudioManager&) = delete;
+  CastAudioManager& operator=(const CastAudioManager&) = delete;
+
   ~CastAudioManager() override;
 
   // AudioManagerBase implementation.
@@ -134,8 +138,6 @@
   // Weak pointers must be dereferenced on the |browser_task_runner|.
   base::WeakPtr<CastAudioManager> weak_this_;
   base::WeakPtrFactory<CastAudioManager> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastAudioManager);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/cast_audio_manager_alsa.h b/chromecast/media/audio/cast_audio_manager_alsa.h
index c8ab7d0c..0f12998 100644
--- a/chromecast/media/audio/cast_audio_manager_alsa.h
+++ b/chromecast/media/audio/cast_audio_manager_alsa.h
@@ -39,6 +39,10 @@
       scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
       external_service_support::ExternalConnector* connector,
       bool use_mixer);
+
+  CastAudioManagerAlsa(const CastAudioManagerAlsa&) = delete;
+  CastAudioManagerAlsa& operator=(const CastAudioManagerAlsa&) = delete;
+
   ~CastAudioManagerAlsa() override;
 
   // CastAudioManager implementation.
@@ -74,8 +78,6 @@
                           ::media::AudioDeviceNames* device_names);
 
   std::unique_ptr<::media::AlsaWrapper> wrapper_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastAudioManagerAlsa);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/cast_audio_mixer.cc b/chromecast/media/audio/cast_audio_mixer.cc
index 3c31a28..510ddf8b 100644
--- a/chromecast/media/audio/cast_audio_mixer.cc
+++ b/chromecast/media/audio/cast_audio_mixer.cc
@@ -36,6 +36,9 @@
     DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_);
   }
 
+  MixerProxyStream(const MixerProxyStream&) = delete;
+  MixerProxyStream& operator=(const MixerProxyStream&) = delete;
+
   ~MixerProxyStream() override {
     DCHECK_CALLED_ON_VALID_THREAD(audio_thread_checker_);
   }
@@ -61,6 +64,9 @@
       DETACH_FROM_THREAD(backend_thread_checker_);
     }
 
+    ResamplerProxy(const ResamplerProxy&) = delete;
+    ResamplerProxy& operator=(const ResamplerProxy&) = delete;
+
     ~ResamplerProxy() override {}
 
    private:
@@ -76,7 +82,6 @@
     std::unique_ptr<::media::AudioConverter> resampler_;
 
     THREAD_CHECKER(backend_thread_checker_);
-    DISALLOW_COPY_AND_ASSIGN(ResamplerProxy);
   };
 
   // ::media::AudioOutputStream implementation
@@ -179,7 +184,6 @@
   std::unique_ptr<ResamplerProxy> proxy_;
 
   THREAD_CHECKER(audio_thread_checker_);
-  DISALLOW_COPY_AND_ASSIGN(MixerProxyStream);
 };
 
 CastAudioMixer::CastAudioMixer(CastAudioManager* audio_manager)
diff --git a/chromecast/media/audio/cast_audio_mixer.h b/chromecast/media/audio/cast_audio_mixer.h
index 571db28..0faeee3 100644
--- a/chromecast/media/audio/cast_audio_mixer.h
+++ b/chromecast/media/audio/cast_audio_mixer.h
@@ -26,6 +26,10 @@
 class CastAudioMixer : public ::media::AudioOutputStream::AudioSourceCallback {
  public:
   explicit CastAudioMixer(CastAudioManager* audio_manager);
+
+  CastAudioMixer(const CastAudioMixer&) = delete;
+  CastAudioMixer& operator=(const CastAudioMixer&) = delete;
+
   ~CastAudioMixer() override;
 
   virtual ::media::AudioOutputStream* MakeStream(
@@ -57,7 +61,6 @@
   ::media::AudioOutputStream* output_stream_;
 
   THREAD_CHECKER(audio_thread_checker_);
-  DISALLOW_COPY_AND_ASSIGN(CastAudioMixer);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc
index 6b7e805..ebde65e 100644
--- a/chromecast/media/audio/cast_audio_output_stream.cc
+++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -92,6 +92,10 @@
  public:
   MixerServiceWrapper(const ::media::AudioParameters& audio_params,
                       const std::string& device_id);
+
+  MixerServiceWrapper(const MixerServiceWrapper&) = delete;
+  MixerServiceWrapper& operator=(const MixerServiceWrapper&) = delete;
+
   ~MixerServiceWrapper() override = default;
 
   void SetRunning(bool running);
@@ -130,8 +134,6 @@
   // Task runner on |io_thread_|.
   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
   THREAD_CHECKER(io_thread_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(MixerServiceWrapper);
 };
 
 CastAudioOutputStream::MixerServiceWrapper::MixerServiceWrapper(
diff --git a/chromecast/media/audio/cast_audio_output_stream.h b/chromecast/media/audio/cast_audio_output_stream.h
index 17e835eb..6fb877c 100644
--- a/chromecast/media/audio/cast_audio_output_stream.h
+++ b/chromecast/media/audio/cast_audio_output_stream.h
@@ -107,6 +107,10 @@
                         const ::media::AudioParameters& audio_params,
                         const std::string& device_id_or_group_id,
                         bool use_mixer_service);
+
+  CastAudioOutputStream(const CastAudioOutputStream&) = delete;
+  CastAudioOutputStream& operator=(const CastAudioOutputStream&) = delete;
+
   ~CastAudioOutputStream() override;
 
   // ::media::AudioOutputStream implementation.
@@ -156,8 +160,6 @@
   THREAD_CHECKER(audio_thread_checker_);
   base::WeakPtr<CastAudioOutputStream> audio_weak_this_;
   base::WeakPtrFactory<CastAudioOutputStream> audio_weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastAudioOutputStream);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/cma_audio_output_stream.h b/chromecast/media/audio/cma_audio_output_stream.h
index 8e081f0..1b5fa87 100644
--- a/chromecast/media/audio/cma_audio_output_stream.h
+++ b/chromecast/media/audio/cma_audio_output_stream.h
@@ -44,6 +44,10 @@
                        base::TimeDelta buffer_duration,
                        const std::string& device_id,
                        CmaBackendFactory* cma_backend_factory);
+
+  CmaAudioOutputStream(const CmaAudioOutputStream&) = delete;
+  CmaAudioOutputStream& operator=(const CmaAudioOutputStream&) = delete;
+
   ~CmaAudioOutputStream() override;
 
   void SetRunning(bool running);
@@ -97,8 +101,6 @@
   ::media::AudioOutputStream::AudioSourceCallback* source_callback_ = nullptr;
 
   THREAD_CHECKER(media_thread_checker_);
-
-  DISALLOW_COPY_AND_ASSIGN(CmaAudioOutputStream);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/interleaved_channel_mixer.h b/chromecast/media/audio/interleaved_channel_mixer.h
index f4010214..1e72c90 100644
--- a/chromecast/media/audio/interleaved_channel_mixer.h
+++ b/chromecast/media/audio/interleaved_channel_mixer.h
@@ -21,6 +21,10 @@
                           ::media::ChannelLayout output_layout,
                           int output_channel_count,
                           int max_frames);
+
+  InterleavedChannelMixer(const InterleavedChannelMixer&) = delete;
+  InterleavedChannelMixer& operator=(const InterleavedChannelMixer&) = delete;
+
   ~InterleavedChannelMixer();
 
   int input_channel_count() const { return input_channel_count_; }
@@ -44,8 +48,6 @@
 
   // Output buffer, if needed.
   std::vector<float> buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(InterleavedChannelMixer);
 };
 
 }  // namespace media
diff --git a/chromecast/media/audio/interleaved_channel_mixer_unittest.cc b/chromecast/media/audio/interleaved_channel_mixer_unittest.cc
index 7fcf76f..3fcd1ef 100644
--- a/chromecast/media/audio/interleaved_channel_mixer_unittest.cc
+++ b/chromecast/media/audio/interleaved_channel_mixer_unittest.cc
@@ -27,10 +27,12 @@
 class InterleavedChannelMixerTest : public testing::TestWithParam<TestParams> {
  public:
   InterleavedChannelMixerTest() = default;
-  ~InterleavedChannelMixerTest() override = default;
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(InterleavedChannelMixerTest);
+  InterleavedChannelMixerTest(const InterleavedChannelMixerTest&) = delete;
+  InterleavedChannelMixerTest& operator=(const InterleavedChannelMixerTest&) =
+      delete;
+
+  ~InterleavedChannelMixerTest() override = default;
 };
 
 TEST_P(InterleavedChannelMixerTest, Transform) {
diff --git a/chromecast/media/audio/mixer_service/control_connection.h b/chromecast/media/audio/mixer_service/control_connection.h
index b008d397..a54b644 100644
--- a/chromecast/media/audio/mixer_service/control_connection.h
+++ b/chromecast/media/audio/mixer_service/control_connection.h
@@ -37,6 +37,10 @@
       base::OnceCallback<void(const std::vector<std::string>&)>;
 
   ControlConnection();
+
+  ControlConnection(const ControlConnection&) = delete;
+  ControlConnection& operator=(const ControlConnection&) = delete;
+
   ~ControlConnection() override;
 
   // Connects to the mixer. If the mixer connection is lost, this will
@@ -111,8 +115,6 @@
   // Uses std::list to trigger callbacks in FIFO order.
   std::list<ListPostprocessorsCallback> list_postprocessors_callbacks_;
   int num_output_channels_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(ControlConnection);
 };
 
 }  // namespace mixer_service
diff --git a/chromecast/media/audio/mixer_service/mixer_connection.h b/chromecast/media/audio/mixer_service/mixer_connection.h
index 641a98a..aeda3d1 100644
--- a/chromecast/media/audio/mixer_service/mixer_connection.h
+++ b/chromecast/media/audio/mixer_service/mixer_connection.h
@@ -25,6 +25,10 @@
 class MixerConnection {
  public:
   MixerConnection();
+
+  MixerConnection(const MixerConnection&) = delete;
+  MixerConnection& operator=(const MixerConnection&) = delete;
+
   virtual ~MixerConnection();
 
   // Initiates connection to the mixer service. Will call OnConnected() when
@@ -46,8 +50,6 @@
   bool log_timeout_ = true;
 
   base::WeakPtrFactory<MixerConnection> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MixerConnection);
 };
 
 }  // namespace mixer_service
diff --git a/chromecast/media/audio/mixer_service/receiver/receiver.cc b/chromecast/media/audio/mixer_service/receiver/receiver.cc
index 4fdde4ba..db97f44 100644
--- a/chromecast/media/audio/mixer_service/receiver/receiver.cc
+++ b/chromecast/media/audio/mixer_service/receiver/receiver.cc
@@ -88,6 +88,9 @@
     socket_->SetDelegate(this);
   }
 
+  InitialSocket(const InitialSocket&) = delete;
+  InitialSocket& operator=(const InitialSocket&) = delete;
+
   ~InitialSocket() override = default;
 
  private:
@@ -120,8 +123,6 @@
 
   Receiver* const receiver_;
   std::unique_ptr<MixerSocket> socket_;
-
-  DISALLOW_COPY_AND_ASSIGN(InitialSocket);
 };
 
 Receiver::Receiver()
diff --git a/chromecast/media/audio/mixer_service/receiver/receiver.h b/chromecast/media/audio/mixer_service/receiver/receiver.h
index 715ebe7..e698cb8 100644
--- a/chromecast/media/audio/mixer_service/receiver/receiver.h
+++ b/chromecast/media/audio/mixer_service/receiver/receiver.h
@@ -26,6 +26,10 @@
 class Receiver : public AudioSocketService::Delegate {
  public:
   Receiver();
+
+  Receiver(const Receiver&) = delete;
+  Receiver& operator=(const Receiver&) = delete;
+
   ~Receiver() override;
 
   virtual void CreateOutputStream(std::unique_ptr<MixerSocket> socket,
@@ -61,8 +65,6 @@
       initial_sockets_;
 
   base::WeakPtrFactory<Receiver> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(Receiver);
 };
 
 }  // namespace mixer_service
diff --git a/chromecast/media/audio/mixer_service/receiver/receiver_cma.cc b/chromecast/media/audio/mixer_service/receiver/receiver_cma.cc
index 5e47f2c7..5d55998 100644
--- a/chromecast/media/audio/mixer_service/receiver/receiver_cma.cc
+++ b/chromecast/media/audio/mixer_service/receiver/receiver_cma.cc
@@ -40,6 +40,9 @@
     socket_->SetDelegate(this);
   }
 
+  UnusedSocket(const UnusedSocket&) = delete;
+  UnusedSocket& operator=(const UnusedSocket&) = delete;
+
   ~UnusedSocket() override = default;
 
  private:
@@ -48,8 +51,6 @@
 
   ReceiverCma* const receiver_;
   const std::unique_ptr<MixerSocket> socket_;
-
-  DISALLOW_COPY_AND_ASSIGN(UnusedSocket);
 };
 
 class ReceiverCma::Stream : public MixerSocket::Delegate,
@@ -66,6 +67,9 @@
                             &Stream::OnInactivityTimeout);
   }
 
+  Stream(const Stream&) = delete;
+  Stream& operator=(const Stream&) = delete;
+
   ~Stream() override = default;
 
   // MixerSocket::Delegate implementation:
@@ -177,8 +181,6 @@
   base::TimeTicks last_receive_time_;
 
   base::WeakPtrFactory<Stream> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(Stream);
 };
 
 ReceiverCma::ReceiverCma(MediaPipelineBackendManager* backend_manager)
diff --git a/chromecast/media/audio/mixer_service/receiver/receiver_cma.h b/chromecast/media/audio/mixer_service/receiver/receiver_cma.h
index 48e4e247..70ae6a6d 100644
--- a/chromecast/media/audio/mixer_service/receiver/receiver_cma.h
+++ b/chromecast/media/audio/mixer_service/receiver/receiver_cma.h
@@ -22,6 +22,10 @@
 class ReceiverCma : public Receiver {
  public:
   explicit ReceiverCma(MediaPipelineBackendManager* backend_manager);
+
+  ReceiverCma(const ReceiverCma&) = delete;
+  ReceiverCma& operator=(const ReceiverCma&) = delete;
+
   ~ReceiverCma() override;
 
   MediaPipelineBackendManager* backend_manager() const {
@@ -51,8 +55,6 @@
 
   base::flat_map<Stream*, std::unique_ptr<Stream>> streams_;
   base::flat_map<UnusedSocket*, std::unique_ptr<UnusedSocket>> unused_sockets_;
-
-  DISALLOW_COPY_AND_ASSIGN(ReceiverCma);
 };
 
 }  // namespace mixer_service
diff --git a/chromecast/media/base/decrypt_context_impl.h b/chromecast/media/base/decrypt_context_impl.h
index 02981b59..7458608f 100644
--- a/chromecast/media/base/decrypt_context_impl.h
+++ b/chromecast/media/base/decrypt_context_impl.h
@@ -33,6 +33,10 @@
   enum class OutputType { kSecure, kClearAllowed, kClearRequired };
 
   explicit DecryptContextImpl(CastKeySystem key_system);
+
+  DecryptContextImpl(const DecryptContextImpl&) = delete;
+  DecryptContextImpl& operator=(const DecryptContextImpl&) = delete;
+
   ~DecryptContextImpl() override;
 
   // DecryptContext implementation:
@@ -57,8 +61,6 @@
 
  private:
   CastKeySystem key_system_;
-
-  DISALLOW_COPY_AND_ASSIGN(DecryptContextImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/base/slew_volume.h b/chromecast/media/base/slew_volume.h
index 62d9d0d2..10b8812 100644
--- a/chromecast/media/base/slew_volume.h
+++ b/chromecast/media/base/slew_volume.h
@@ -21,6 +21,10 @@
   // Use raised negative cosine function when |use_cosine_slew| is true and
   // linear otherwise.
   SlewVolume(int max_slew_time_ms, bool use_cosine_slew);
+
+  SlewVolume(const SlewVolume&) = delete;
+  SlewVolume& operator=(const SlewVolume&) = delete;
+
   ~SlewVolume() = default;
 
   void SetSampleRate(int sample_rate);
@@ -85,7 +89,6 @@
   double slew_offset_;
   double slew_cos_;
   double slew_sin_;
-  DISALLOW_COPY_AND_ASSIGN(SlewVolume);
 };
 
 }  // namespace media
diff --git a/chromecast/media/base/supported_codec_profile_levels_memo.h b/chromecast/media/base/supported_codec_profile_levels_memo.h
index 3374da0..656c413e 100644
--- a/chromecast/media/base/supported_codec_profile_levels_memo.h
+++ b/chromecast/media/base/supported_codec_profile_levels_memo.h
@@ -20,6 +20,12 @@
 class SupportedCodecProfileLevelsMemo {
  public:
   SupportedCodecProfileLevelsMemo();
+
+  SupportedCodecProfileLevelsMemo(const SupportedCodecProfileLevelsMemo&) =
+      delete;
+  SupportedCodecProfileLevelsMemo& operator=(
+      const SupportedCodecProfileLevelsMemo&) = delete;
+
   ~SupportedCodecProfileLevelsMemo();
   void AddSupportedCodecProfileLevel(CodecProfileLevel codec_profile_level);
   bool IsSupportedVideoConfig(VideoCodec codec,
@@ -29,8 +35,6 @@
  private:
   mutable base::Lock lock_;
   std::vector<CodecProfileLevel> codec_profile_levels_;
-
-  DISALLOW_COPY_AND_ASSIGN(SupportedCodecProfileLevelsMemo);
 };
 
 }  // namespace media
diff --git a/chromecast/media/base/video_plane_controller.h b/chromecast/media/base/video_plane_controller.h
index 9bda553..b3d66565 100644
--- a/chromecast/media/base/video_plane_controller.h
+++ b/chromecast/media/base/video_plane_controller.h
@@ -37,6 +37,10 @@
   VideoPlaneController(
       const Size& graphics_resolution,
       scoped_refptr<base::SingleThreadTaskRunner> media_task_runner);
+
+  VideoPlaneController(const VideoPlaneController&) = delete;
+  VideoPlaneController& operator=(const VideoPlaneController&) = delete;
+
   ~VideoPlaneController();
 
   // Sets the video plane geometry in *graphics plane coordinates*. If there is
@@ -95,8 +99,6 @@
   scoped_refptr<RateLimitedSetVideoPlaneGeometry> video_plane_wrapper_;
 
   base::ThreadChecker thread_checker_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoPlaneController);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cdm/cast_cdm.cc b/chromecast/media/cdm/cast_cdm.cc
index 37f181e..b932611 100644
--- a/chromecast/media/cdm/cast_cdm.cc
+++ b/chromecast/media/cdm/cast_cdm.cc
@@ -33,6 +33,10 @@
   explicit CastCdmContextImpl(CastCdm* cast_cdm) : cast_cdm_(cast_cdm) {
     DCHECK(cast_cdm_);
   }
+
+  CastCdmContextImpl(const CastCdmContextImpl&) = delete;
+  CastCdmContextImpl& operator=(const CastCdmContextImpl&) = delete;
+
   ~CastCdmContextImpl() override = default;
 
   std::unique_ptr<::media::CallbackRegistration> RegisterEventCB(
@@ -59,8 +63,6 @@
  private:
   // The CastCdm object which owns |this|.
   CastCdm* const cast_cdm_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastCdmContextImpl);
 };
 
 // Returns the HDCP version multiplied by ten.
diff --git a/chromecast/media/cdm/cast_cdm_factory.h b/chromecast/media/cdm/cast_cdm_factory.h
index 1082ea6..57ac3880 100644
--- a/chromecast/media/cdm/cast_cdm_factory.h
+++ b/chromecast/media/cdm/cast_cdm_factory.h
@@ -30,6 +30,10 @@
   CastCdmFactory(scoped_refptr<base::SingleThreadTaskRunner> task_runner,
                  const url::Origin& cdm_origin,
                  MediaResourceTracker* media_resource_tracker);
+
+  CastCdmFactory(const CastCdmFactory&) = delete;
+  CastCdmFactory& operator=(const CastCdmFactory&) = delete;
+
   ~CastCdmFactory() override;
 
   // ::media::CdmFactory implementation:
@@ -54,8 +58,6 @@
  private:
   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   const url::Origin cdm_origin_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastCdmFactory);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cdm/playready_drm_delegate_android.h b/chromecast/media/cdm/playready_drm_delegate_android.h
index 76fcdf6..31e5bcf 100644
--- a/chromecast/media/cdm/playready_drm_delegate_android.h
+++ b/chromecast/media/cdm/playready_drm_delegate_android.h
@@ -16,6 +16,11 @@
 class PlayreadyDrmDelegateAndroid : public ::media::MediaDrmBridgeDelegate {
  public:
   PlayreadyDrmDelegateAndroid();
+
+  PlayreadyDrmDelegateAndroid(const PlayreadyDrmDelegateAndroid&) = delete;
+  PlayreadyDrmDelegateAndroid& operator=(const PlayreadyDrmDelegateAndroid&) =
+      delete;
+
   ~PlayreadyDrmDelegateAndroid() override;
 
   // ::media::MediaDrmBridgeDelegate implementation:
@@ -25,9 +30,6 @@
       const std::vector<uint8_t>& init_data,
       std::vector<uint8_t>* init_data_out,
       std::vector<std::string>* optional_parameters_out) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PlayreadyDrmDelegateAndroid);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/alsa/alsa_volume_control.h b/chromecast/media/cma/backend/alsa/alsa_volume_control.h
index 626c0c5..71d228b00 100644
--- a/chromecast/media/cma/backend/alsa/alsa_volume_control.h
+++ b/chromecast/media/cma/backend/alsa/alsa_volume_control.h
@@ -24,6 +24,10 @@
                           public base::MessagePumpForIO::FdWatcher {
  public:
   explicit AlsaVolumeControl(Delegate* delegate);
+
+  AlsaVolumeControl(const AlsaVolumeControl&) = delete;
+  AlsaVolumeControl& operator=(const AlsaVolumeControl&) = delete;
+
   ~AlsaVolumeControl() override;
 
   // SystemVolumeControl interface.
@@ -89,8 +93,6 @@
 
   std::vector<std::unique_ptr<base::MessagePumpForIO::FdWatchController>>
       file_descriptor_watchers_;
-
-  DISALLOW_COPY_AND_ASSIGN(AlsaVolumeControl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/alsa/alsa_wrapper.h b/chromecast/media/cma/backend/alsa/alsa_wrapper.h
index eeb0d88..09cae1b 100644
--- a/chromecast/media/cma/backend/alsa/alsa_wrapper.h
+++ b/chromecast/media/cma/backend/alsa/alsa_wrapper.h
@@ -17,6 +17,10 @@
 class AlsaWrapper : public ::media::AlsaWrapper {
  public:
   AlsaWrapper();
+
+  AlsaWrapper(const AlsaWrapper&) = delete;
+  AlsaWrapper& operator=(const AlsaWrapper&) = delete;
+
   ~AlsaWrapper() override;
 
   virtual int PcmPause(snd_pcm_t* handle, int enable);
@@ -43,9 +47,6 @@
   virtual int PcmSwParamsSetTstampType(snd_pcm_t* handle,
                                        snd_pcm_sw_params_t* obj,
                                        int val);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AlsaWrapper);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h
index 6d4ef72e..272780c 100644
--- a/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h
+++ b/chromecast/media/cma/backend/alsa/mixer_output_stream_alsa.h
@@ -22,6 +22,10 @@
 class MixerOutputStreamAlsa : public MixerOutputStream {
  public:
   MixerOutputStreamAlsa();
+
+  MixerOutputStreamAlsa(const MixerOutputStreamAlsa&) = delete;
+  MixerOutputStreamAlsa& operator=(const MixerOutputStreamAlsa&) = delete;
+
   ~MixerOutputStreamAlsa() override;
 
   void SetAlsaWrapperForTest(std::unique_ptr<AlsaWrapper> alsa);
@@ -83,8 +87,6 @@
   MediaPipelineBackend::AudioDecoder::RenderingDelay rendering_delay_;
 
   std::vector<uint8_t> output_buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(MixerOutputStreamAlsa);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/android/audio_decoder_android.h b/chromecast/media/cma/backend/android/audio_decoder_android.h
index bf5f1a1..6af04f02 100644
--- a/chromecast/media/cma/backend/android/audio_decoder_android.h
+++ b/chromecast/media/cma/backend/android/audio_decoder_android.h
@@ -42,6 +42,10 @@
   using BufferStatus = MediaPipelineBackend::BufferStatus;
 
   explicit AudioDecoderAndroid(MediaPipelineBackendAndroid* backend);
+
+  AudioDecoderAndroid(const AudioDecoderAndroid&) = delete;
+  AudioDecoderAndroid& operator=(const AudioDecoderAndroid&) = delete;
+
   ~AudioDecoderAndroid() override;
 
   void Initialize();
@@ -120,8 +124,6 @@
   scoped_refptr<::media::AudioBufferMemoryPool> pool_;
 
   base::WeakPtrFactory<AudioDecoderAndroid> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioDecoderAndroid);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/android/audio_sink_android.h b/chromecast/media/cma/backend/android/audio_sink_android.h
index f9cd4c6..f5dce59e 100644
--- a/chromecast/media/cma/backend/android/audio_sink_android.h
+++ b/chromecast/media/cma/backend/android/audio_sink_android.h
@@ -110,6 +110,10 @@
   using Delegate = AudioSinkAndroid::Delegate;
 
   explicit ManagedAudioSink(SinkType sink_type);
+
+  ManagedAudioSink(const ManagedAudioSink&) = delete;
+  ManagedAudioSink& operator=(const ManagedAudioSink&) = delete;
+
   ~ManagedAudioSink();
 
   // Resets the sink_ object by removing it from the manager and deleting it.
@@ -133,8 +137,6 @@
 
   SinkType sink_type_;
   AudioSinkAndroid* sink_;
-
-  DISALLOW_COPY_AND_ASSIGN(ManagedAudioSink);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/android/audio_sink_manager.cc b/chromecast/media/cma/backend/android/audio_sink_manager.cc
index b3f58cb..4b86c343 100644
--- a/chromecast/media/cma/backend/android/audio_sink_manager.cc
+++ b/chromecast/media/cma/backend/android/audio_sink_manager.cc
@@ -18,10 +18,11 @@
 class AudioSinkManagerInstance : public AudioSinkManager {
  public:
   AudioSinkManagerInstance() {}
-  ~AudioSinkManagerInstance() override {}
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(AudioSinkManagerInstance);
+  AudioSinkManagerInstance(const AudioSinkManagerInstance&) = delete;
+  AudioSinkManagerInstance& operator=(const AudioSinkManagerInstance&) = delete;
+
+  ~AudioSinkManagerInstance() override {}
 };
 
 }  // namespace
diff --git a/chromecast/media/cma/backend/android/media_pipeline_backend_android.h b/chromecast/media/cma/backend/android/media_pipeline_backend_android.h
index 36d7a37..91da1c4 100644
--- a/chromecast/media/cma/backend/android/media_pipeline_backend_android.h
+++ b/chromecast/media/cma/backend/android/media_pipeline_backend_android.h
@@ -31,6 +31,11 @@
   using RenderingDelay = AudioDecoder::RenderingDelay;
 
   explicit MediaPipelineBackendAndroid(const MediaPipelineDeviceParams& params);
+
+  MediaPipelineBackendAndroid(const MediaPipelineBackendAndroid&) = delete;
+  MediaPipelineBackendAndroid& operator=(const MediaPipelineBackendAndroid&) =
+      delete;
+
   ~MediaPipelineBackendAndroid() override;
 
   // MediaPipelineBackend implementation:
@@ -63,8 +68,6 @@
   const MediaPipelineDeviceParams params_;
   std::unique_ptr<VideoDecoderNull> video_decoder_;
   std::unique_ptr<AudioDecoderAndroid> audio_decoder_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaPipelineBackendAndroid);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/android/volume_cache.h b/chromecast/media/cma/backend/android/volume_cache.h
index a509e19c..0b481b1 100644
--- a/chromecast/media/cma/backend/android/volume_cache.h
+++ b/chromecast/media/cma/backend/android/volume_cache.h
@@ -28,6 +28,10 @@
 class VolumeCache {
  public:
   VolumeCache(AudioContentType type, SystemVolumeTableAccessApi* api);
+
+  VolumeCache(const VolumeCache&) = delete;
+  VolumeCache& operator=(const VolumeCache&) = delete;
+
   ~VolumeCache();
 
   // Returns the mapped and interpolated dBFS value for the given volume level,
@@ -42,8 +46,6 @@
   const int kMaxVolumeIndex;
 
   std::vector<float> cache_;
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeCache);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/android/volume_control_android.h b/chromecast/media/cma/backend/android/volume_control_android.h
index 1a20032..ed67633 100644
--- a/chromecast/media/cma/backend/android/volume_control_android.h
+++ b/chromecast/media/cma/backend/android/volume_control_android.h
@@ -22,6 +22,10 @@
 class VolumeControlAndroid : SystemVolumeTableAccessApi {
  public:
   VolumeControlAndroid();
+
+  VolumeControlAndroid(const VolumeControlAndroid&) = delete;
+  VolumeControlAndroid& operator=(const VolumeControlAndroid&) = delete;
+
   ~VolumeControlAndroid() override;
 
   void AddVolumeObserver(VolumeObserver* observer);
@@ -83,8 +87,6 @@
 
   base::Thread thread_;
   base::WaitableEvent initialize_complete_event_;
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeControlAndroid);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/audio_decoder_for_mixer.h b/chromecast/media/cma/backend/audio_decoder_for_mixer.h
index 3aafdb412..21168a40 100644
--- a/chromecast/media/cma/backend/audio_decoder_for_mixer.h
+++ b/chromecast/media/cma/backend/audio_decoder_for_mixer.h
@@ -36,6 +36,10 @@
   using BufferStatus = MediaPipelineBackend::BufferStatus;
 
   explicit AudioDecoderForMixer(MediaPipelineBackendForMixer* backend);
+
+  AudioDecoderForMixer(const AudioDecoderForMixer&) = delete;
+  AudioDecoderForMixer& operator=(const AudioDecoderForMixer&) = delete;
+
   ~AudioDecoderForMixer() override;
 
   virtual void Initialize();
@@ -128,8 +132,6 @@
   bool start_playback_asap_ = false;
 
   base::WeakPtrFactory<AudioDecoderForMixer> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioDecoderForMixer);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
index 9a7a960..947776e 100644
--- a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
+++ b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
@@ -103,6 +103,10 @@
 class BufferFeeder : public MediaPipelineBackend::Decoder::Delegate {
  public:
   explicit BufferFeeder(base::OnceClosure eos_cb);
+
+  BufferFeeder(const BufferFeeder&) = delete;
+  BufferFeeder& operator=(const BufferFeeder&) = delete;
+
   ~BufferFeeder() override {}
 
   static std::unique_ptr<BufferFeeder> LoadAudio(MediaPipelineBackend* backend,
@@ -166,8 +170,6 @@
   VideoConfig video_config_;
   int64_t last_pushed_pts_;
   std::unique_ptr<::media::AudioTimestampHelper> timestamp_helper_;
-
-  DISALLOW_COPY_AND_ASSIGN(BufferFeeder);
 };
 
 }  // namespace
@@ -184,6 +186,11 @@
   };
 
   AudioVideoPipelineDeviceTest();
+
+  AudioVideoPipelineDeviceTest(const AudioVideoPipelineDeviceTest&) = delete;
+  AudioVideoPipelineDeviceTest& operator=(const AudioVideoPipelineDeviceTest&) =
+      delete;
+
   ~AudioVideoPipelineDeviceTest() override;
 
   MediaPipelineBackend* backend() const { return backend_.get(); }
@@ -263,8 +270,6 @@
   // Pause settings
   std::vector<PauseInfo> pause_pattern_;
   size_t pause_pattern_idx_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioVideoPipelineDeviceTest);
 };
 
 namespace {
diff --git a/chromecast/media/cma/backend/cast_audio_json.h b/chromecast/media/cma/backend/cast_audio_json.h
index 99dadec..556f768d 100644
--- a/chromecast/media/cma/backend/cast_audio_json.h
+++ b/chromecast/media/cma/backend/cast_audio_json.h
@@ -52,6 +52,11 @@
 class CastAudioJsonProviderImpl : public CastAudioJsonProvider {
  public:
   CastAudioJsonProviderImpl();
+
+  CastAudioJsonProviderImpl(const CastAudioJsonProviderImpl&) = delete;
+  CastAudioJsonProviderImpl& operator=(const CastAudioJsonProviderImpl&) =
+      delete;
+
   ~CastAudioJsonProviderImpl() override;
 
  private:
@@ -71,8 +76,6 @@
   void SetTuningChangedCallback(TuningChangedCallback callback) override;
 
   base::SequenceBound<FileWatcher> cast_audio_watcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastAudioJsonProviderImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/cma_backend_factory_impl.h b/chromecast/media/cma/backend/cma_backend_factory_impl.h
index cd99014..120feb3 100644
--- a/chromecast/media/cma/backend/cma_backend_factory_impl.h
+++ b/chromecast/media/cma/backend/cma_backend_factory_impl.h
@@ -24,6 +24,10 @@
   // dependencies are removed from the internal implemenation.
   explicit CmaBackendFactoryImpl(
       MediaPipelineBackendManager* media_pipeline_backend_manager);
+
+  CmaBackendFactoryImpl(const CmaBackendFactoryImpl&) = delete;
+  CmaBackendFactoryImpl& operator=(const CmaBackendFactoryImpl&) = delete;
+
   ~CmaBackendFactoryImpl() override;
 
   std::unique_ptr<CmaBackend> CreateBackend(
@@ -36,8 +40,6 @@
 
  private:
   media::MediaPipelineBackendManager* const media_pipeline_backend_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(CmaBackendFactoryImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/cplay/cplay.cc b/chromecast/media/cma/backend/cplay/cplay.cc
index 0fe6353..f21d0cc 100644
--- a/chromecast/media/cma/backend/cplay/cplay.cc
+++ b/chromecast/media/cma/backend/cplay/cplay.cc
@@ -100,6 +100,9 @@
               << "s.";
   }
 
+  WavMixerInputSource(const WavMixerInputSource&) = delete;
+  WavMixerInputSource& operator=(const WavMixerInputSource&) = delete;
+
   ~WavMixerInputSource() override = default;
 
   bool AtEnd() { return input_handler_->AtEnd(cursor_); }
@@ -154,8 +157,6 @@
   size_t cursor_ = 0;
   const std::string device_id_;
   const size_t bytes_per_frame_;
-
-  DISALLOW_COPY_AND_ASSIGN(WavMixerInputSource);
 };
 
 // OutputHandler interface to allow switching between alsa and file output.
@@ -184,6 +185,9 @@
                                 sizeof(header_));
   }
 
+  WavOutputHandler(const WavOutputHandler&) = delete;
+  WavOutputHandler& operator=(const WavOutputHandler&) = delete;
+
   ~WavOutputHandler() override {
     // Update size and re-write header. We only really need to overwrite 8 bytes
     // but it is easy and cheap to overwrite the whole header.
@@ -211,13 +215,15 @@
   WavHeader header_;
   base::File wav_file_;
   const int num_channels_;
-
-  DISALLOW_COPY_AND_ASSIGN(WavOutputHandler);
 };
 
 class AudioMetrics {
  public:
   AudioMetrics(int num_channels) : num_channels_(num_channels) {}
+
+  AudioMetrics(const AudioMetrics&) = delete;
+  AudioMetrics& operator=(const AudioMetrics&) = delete;
+
   ~AudioMetrics() = default;
 
   void ProcessFrames(float* data, int num_frames) {
@@ -248,8 +254,6 @@
   int total_samples_ = 0;
   float largest_sample_ = 0.0f;
   double squared_sum_ = 0.0;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioMetrics);
 };
 
 Parameters ReadArgs(int argc, char* argv[]) {
diff --git a/chromecast/media/cma/backend/desktop/audio_decoder_desktop.h b/chromecast/media/cma/backend/desktop/audio_decoder_desktop.h
index aba6948..ae6967d 100644
--- a/chromecast/media/cma/backend/desktop/audio_decoder_desktop.h
+++ b/chromecast/media/cma/backend/desktop/audio_decoder_desktop.h
@@ -19,6 +19,10 @@
 class AudioDecoderDesktop : public MediaPipelineBackend::AudioDecoder {
  public:
   AudioDecoderDesktop();
+
+  AudioDecoderDesktop(const AudioDecoderDesktop&) = delete;
+  AudioDecoderDesktop& operator=(const AudioDecoderDesktop&) = delete;
+
   ~AudioDecoderDesktop() override;
 
   void Start(base::TimeDelta start_pts);
@@ -38,7 +42,6 @@
  private:
   Delegate* delegate_;
   std::unique_ptr<MediaSinkDesktop> sink_;
-  DISALLOW_COPY_AND_ASSIGN(AudioDecoderDesktop);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/desktop/media_pipeline_backend_desktop.h b/chromecast/media/cma/backend/desktop/media_pipeline_backend_desktop.h
index 66029f4..ff9d37bd 100644
--- a/chromecast/media/cma/backend/desktop/media_pipeline_backend_desktop.h
+++ b/chromecast/media/cma/backend/desktop/media_pipeline_backend_desktop.h
@@ -21,6 +21,11 @@
 class MediaPipelineBackendDesktop : public MediaPipelineBackend {
  public:
   MediaPipelineBackendDesktop();
+
+  MediaPipelineBackendDesktop(const MediaPipelineBackendDesktop&) = delete;
+  MediaPipelineBackendDesktop& operator=(const MediaPipelineBackendDesktop&) =
+      delete;
+
   ~MediaPipelineBackendDesktop() override;
 
   const AudioDecoderDesktop* audio_decoder() const {
@@ -52,8 +57,6 @@
   float rate_;
   std::unique_ptr<AudioDecoderDesktop> audio_decoder_;
   std::unique_ptr<VideoDecoderDesktop> video_decoder_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaPipelineBackendDesktop);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/desktop/media_sink_desktop.h b/chromecast/media/cma/backend/desktop/media_sink_desktop.h
index ab9023e..3c6548f 100644
--- a/chromecast/media/cma/backend/desktop/media_sink_desktop.h
+++ b/chromecast/media/cma/backend/desktop/media_sink_desktop.h
@@ -18,6 +18,10 @@
  public:
   MediaSinkDesktop(MediaPipelineBackend::Decoder::Delegate* delegate,
                    base::TimeDelta start_pts);
+
+  MediaSinkDesktop(const MediaSinkDesktop&) = delete;
+  MediaSinkDesktop& operator=(const MediaSinkDesktop&) = delete;
+
   ~MediaSinkDesktop();
 
   void SetPlaybackRate(float rate);
@@ -34,8 +38,6 @@
   base::TimeDelta last_frame_pts_;
   bool received_eos_;
   base::CancelableOnceClosure eos_task_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaSinkDesktop);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/desktop/video_decoder_desktop.h b/chromecast/media/cma/backend/desktop/video_decoder_desktop.h
index d237660..4fe56ad 100644
--- a/chromecast/media/cma/backend/desktop/video_decoder_desktop.h
+++ b/chromecast/media/cma/backend/desktop/video_decoder_desktop.h
@@ -19,6 +19,10 @@
 class VideoDecoderDesktop : public MediaPipelineBackend::VideoDecoder {
  public:
   VideoDecoderDesktop();
+
+  VideoDecoderDesktop(const VideoDecoderDesktop&) = delete;
+  VideoDecoderDesktop& operator=(const VideoDecoderDesktop&) = delete;
+
   ~VideoDecoderDesktop() override;
 
   void Start(base::TimeDelta start_pts);
@@ -36,7 +40,6 @@
  private:
   Delegate* delegate_;
   std::unique_ptr<MediaSinkDesktop> sink_;
-  DISALLOW_COPY_AND_ASSIGN(VideoDecoderDesktop);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/desktop/volume_control_desktop.cc b/chromecast/media/cma/backend/desktop/volume_control_desktop.cc
index 814c1d8..b3951ea 100644
--- a/chromecast/media/cma/backend/desktop/volume_control_desktop.cc
+++ b/chromecast/media/cma/backend/desktop/volume_control_desktop.cc
@@ -44,6 +44,9 @@
     thread_.StartWithOptions(std::move(options));
   }
 
+  VolumeControlInternal(const VolumeControlInternal&) = delete;
+  VolumeControlInternal& operator=(const VolumeControlInternal&) = delete;
+
   ~VolumeControlInternal() = default;
 
   void AddVolumeObserver(VolumeObserver* observer) {
@@ -148,8 +151,6 @@
   std::vector<VolumeObserver*> volume_observers_;
 
   base::Thread thread_;
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeControlInternal);
 };
 
 VolumeControlInternal& GetVolumeControl() {
diff --git a/chromecast/media/cma/backend/fuchsia/fuchsia_volume_control.h b/chromecast/media/cma/backend/fuchsia/fuchsia_volume_control.h
index 0216179..8abf3c2 100644
--- a/chromecast/media/cma/backend/fuchsia/fuchsia_volume_control.h
+++ b/chromecast/media/cma/backend/fuchsia/fuchsia_volume_control.h
@@ -16,6 +16,10 @@
 class FuchsiaVolumeControl : public SystemVolumeControl {
  public:
   FuchsiaVolumeControl();
+
+  FuchsiaVolumeControl(const FuchsiaVolumeControl&) = delete;
+  FuchsiaVolumeControl& operator=(const FuchsiaVolumeControl&) = delete;
+
   ~FuchsiaVolumeControl() override;
 
   // SystemVolumeControl interface.
@@ -26,9 +30,6 @@
   void SetMuted(bool muted) override;
   void SetPowerSave(bool power_save_on) override;
   void SetLimit(float limit) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FuchsiaVolumeControl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h b/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h
index 192d3b1..752d6a37 100644
--- a/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h
+++ b/chromecast/media/cma/backend/fuchsia/mixer_output_stream_fuchsia.h
@@ -18,6 +18,10 @@
 class MixerOutputStreamFuchsia : public MixerOutputStream {
  public:
   MixerOutputStreamFuchsia();
+
+  MixerOutputStreamFuchsia(const MixerOutputStreamFuchsia&) = delete;
+  MixerOutputStreamFuchsia& operator=(const MixerOutputStreamFuchsia&) = delete;
+
   ~MixerOutputStreamFuchsia() override;
 
   // MixerOutputStream implementation:
@@ -63,8 +67,6 @@
   // AudioRenderer::OnMinLeadTimeChanged event. Assume 50ms until we get the
   // first OnMinLeadTimeChanged event.
   base::TimeDelta min_lead_time_ = base::TimeDelta::FromMilliseconds(50);
-
-  DISALLOW_COPY_AND_ASSIGN(MixerOutputStreamFuchsia);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/media_pipeline_backend_for_mixer.h b/chromecast/media/cma/backend/media_pipeline_backend_for_mixer.h
index 8c58f7f..142564e 100644
--- a/chromecast/media/cma/backend/media_pipeline_backend_for_mixer.h
+++ b/chromecast/media/cma/backend/media_pipeline_backend_for_mixer.h
@@ -33,6 +33,11 @@
  public:
   explicit MediaPipelineBackendForMixer(
       const MediaPipelineDeviceParams& params);
+
+  MediaPipelineBackendForMixer(const MediaPipelineBackendForMixer&) = delete;
+  MediaPipelineBackendForMixer& operator=(const MediaPipelineBackendForMixer&) =
+      delete;
+
   ~MediaPipelineBackendForMixer() override;
 
   // MediaPipelineBackend implementation:
@@ -102,8 +107,6 @@
 
   base::WeakPtr<MediaPipelineBackendForMixer> weak_this_;
   base::WeakPtrFactory<MediaPipelineBackendForMixer> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaPipelineBackendForMixer);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/audio_output_redirector.cc b/chromecast/media/cma/backend/mixer/audio_output_redirector.cc
index 8843269d..15da86a 100644
--- a/chromecast/media/cma/backend/mixer/audio_output_redirector.cc
+++ b/chromecast/media/cma/backend/mixer/audio_output_redirector.cc
@@ -73,6 +73,9 @@
     socket_->SetDelegate(this);
   }
 
+  RedirectionConnection(const RedirectionConnection&) = delete;
+  RedirectionConnection& operator=(const RedirectionConnection&) = delete;
+
   ~RedirectionConnection() override = default;
 
   void SetStreamConfig(SampleFormat sample_format,
@@ -141,8 +144,6 @@
 
   bool error_ = false;
   bool sent_stream_config_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(RedirectionConnection);
 };
 
 class AudioOutputRedirector::InputImpl : public AudioOutputRedirectorInput {
@@ -150,6 +151,10 @@
   using RenderingDelay = MediaPipelineBackend::AudioDecoder::RenderingDelay;
 
   InputImpl(AudioOutputRedirector* output_redirector, MixerInput* mixer_input);
+
+  InputImpl(const InputImpl&) = delete;
+  InputImpl& operator=(const InputImpl&) = delete;
+
   ~InputImpl() override;
 
   // AudioOutputRedirectorInput implementation:
@@ -172,8 +177,6 @@
 
   std::unique_ptr<::media::ChannelMixer> channel_mixer_;
   std::unique_ptr<::media::AudioBus> temp_buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(InputImpl);
 };
 
 AudioOutputRedirector::InputImpl::InputImpl(
diff --git a/chromecast/media/cma/backend/mixer/audio_output_redirector.h b/chromecast/media/cma/backend/mixer/audio_output_redirector.h
index 81b5fe8f..ae6949d 100644
--- a/chromecast/media/cma/backend/mixer/audio_output_redirector.h
+++ b/chromecast/media/cma/backend/mixer/audio_output_redirector.h
@@ -58,6 +58,10 @@
   AudioOutputRedirector(StreamMixer* mixer,
                         std::unique_ptr<mixer_service::MixerSocket> socket,
                         const mixer_service::Generic& message);
+
+  AudioOutputRedirector(const AudioOutputRedirector&) = delete;
+  AudioOutputRedirector& operator=(const AudioOutputRedirector&) = delete;
+
   ~AudioOutputRedirector();
 
   int order() const { return config_.order; }
@@ -134,8 +138,6 @@
   base::flat_set<MixerInput*> non_redirected_inputs_;
 
   base::WeakPtrFactory<AudioOutputRedirector> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioOutputRedirector);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/filter_group.h b/chromecast/media/cma/backend/mixer/filter_group.h
index 18bc3b96..9ecdf10 100644
--- a/chromecast/media/cma/backend/mixer/filter_group.h
+++ b/chromecast/media/cma/backend/mixer/filter_group.h
@@ -48,6 +48,9 @@
               std::unique_ptr<PostProcessingPipeline> pipeline,
               const base::Value* volume_limits);
 
+  FilterGroup(const FilterGroup&) = delete;
+  FilterGroup& operator=(const FilterGroup&) = delete;
+
   ~FilterGroup();
 
   int num_channels() const { return num_channels_; }
@@ -169,8 +172,6 @@
   AlignedBuffer<float> interleaved_;
 
   std::unique_ptr<PostProcessingPipeline> post_processing_pipeline_;
-
-  DISALLOW_COPY_AND_ASSIGN(FilterGroup);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/filter_group_unittest.cc b/chromecast/media/cma/backend/mixer/filter_group_unittest.cc
index d74b5f7..9a6064e 100644
--- a/chromecast/media/cma/backend/mixer/filter_group_unittest.cc
+++ b/chromecast/media/cma/backend/mixer/filter_group_unittest.cc
@@ -46,6 +46,10 @@
             testing::Invoke(this, &MockPostProcessingPipeline::StorePtr));
   }
 
+  MockPostProcessingPipeline(const MockPostProcessingPipeline&) = delete;
+  MockPostProcessingPipeline& operator=(const MockPostProcessingPipeline&) =
+      delete;
+
   ~MockPostProcessingPipeline() override {}
   MOCK_METHOD5(ProcessFrames,
                double(float* data,
@@ -81,8 +85,6 @@
   float* output_buffer_;
   const int num_output_channels_;
   int sample_rate_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockPostProcessingPipeline);
 };
 
 // PostProcessor that inverts one channel.
@@ -96,6 +98,10 @@
             this, &InvertChannelPostProcessor::DoInvertChannel));
   }
 
+  InvertChannelPostProcessor(const InvertChannelPostProcessor&) = delete;
+  InvertChannelPostProcessor& operator=(const InvertChannelPostProcessor&) =
+      delete;
+
   ~InvertChannelPostProcessor() override {}
 
   MOCK_METHOD5(ProcessFrames,
@@ -127,8 +133,6 @@
   std::string name() const { return "invert"; }
 
   int channel_to_invert_;
-
-  DISALLOW_COPY_AND_ASSIGN(InvertChannelPostProcessor);
 };
 
 }  // namespace
diff --git a/chromecast/media/cma/backend/mixer/loopback_handler.cc b/chromecast/media/cma/backend/mixer/loopback_handler.cc
index a972097..fd8c6e5 100644
--- a/chromecast/media/cma/backend/mixer/loopback_handler.cc
+++ b/chromecast/media/cma/backend/mixer/loopback_handler.cc
@@ -25,6 +25,10 @@
 class LoopbackHandler::LoopbackIO {
  public:
   LoopbackIO() = default;
+
+  LoopbackIO(const LoopbackIO&) = delete;
+  LoopbackIO& operator=(const LoopbackIO&) = delete;
+
   ~LoopbackIO() = default;
 
   void AddConnection(std::unique_ptr<MixerLoopbackConnection> connection) {
@@ -80,8 +84,6 @@
   int sample_rate_ = 0;
   int num_channels_ = 0;
   int data_size_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(LoopbackIO);
 };
 
 class LoopbackHandler::ExternalLoopbackHandler
diff --git a/chromecast/media/cma/backend/mixer/loopback_handler.h b/chromecast/media/cma/backend/mixer/loopback_handler.h
index 6e3c2a0..32a13b2 100644
--- a/chromecast/media/cma/backend/mixer/loopback_handler.h
+++ b/chromecast/media/cma/backend/mixer/loopback_handler.h
@@ -31,6 +31,10 @@
       scoped_refptr<base::SequencedTaskRunner> io_task_runner);
   LoopbackHandler(scoped_refptr<base::SequencedTaskRunner> io_task_runner,
                   bool use_external_audio_pipeline);
+
+  LoopbackHandler(const LoopbackHandler&) = delete;
+  LoopbackHandler& operator=(const LoopbackHandler&) = delete;
+
   ~LoopbackHandler();
 
   // Adds a new loopback connection.
@@ -75,8 +79,6 @@
 
   base::SequenceBound<LoopbackIO> io_;
   std::unique_ptr<ExternalLoopbackHandler, ExternalDeleter> external_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(LoopbackHandler);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/mixer_input_connection.h b/chromecast/media/cma/backend/mixer/mixer_input_connection.h
index adc705eb..d8f83cd 100644
--- a/chromecast/media/cma/backend/mixer/mixer_input_connection.h
+++ b/chromecast/media/cma/backend/mixer/mixer_input_connection.h
@@ -64,6 +64,9 @@
                        std::unique_ptr<mixer_service::MixerSocket> socket,
                        const mixer_service::OutputStreamParams& params);
 
+  MixerInputConnection(const MixerInputConnection&) = delete;
+  MixerInputConnection& operator=(const MixerInputConnection&) = delete;
+
   // Only public to allow task_runner->DeleteSoon() to work.
   ~MixerInputConnection() override;
 
@@ -225,8 +228,6 @@
 
   base::WeakPtr<MixerInputConnection> weak_this_;
   base::WeakPtrFactory<MixerInputConnection> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MixerInputConnection);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/mixer_loopback_connection.h b/chromecast/media/cma/backend/mixer/mixer_loopback_connection.h
index 6a862c3..768c8e81 100644
--- a/chromecast/media/cma/backend/mixer/mixer_loopback_connection.h
+++ b/chromecast/media/cma/backend/mixer/mixer_loopback_connection.h
@@ -30,6 +30,10 @@
  public:
   explicit MixerLoopbackConnection(
       std::unique_ptr<mixer_service::MixerSocket> socket);
+
+  MixerLoopbackConnection(const MixerLoopbackConnection&) = delete;
+  MixerLoopbackConnection& operator=(const MixerLoopbackConnection&) = delete;
+
   ~MixerLoopbackConnection() override;
 
   void SetErrorCallback(base::OnceClosure callback);
@@ -57,8 +61,6 @@
 
   bool pending_error_ = false;
   bool sent_stream_config_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(MixerLoopbackConnection);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/mixer_pipeline.h b/chromecast/media/cma/backend/mixer/mixer_pipeline.h
index 34482eca..34c1015 100644
--- a/chromecast/media/cma/backend/mixer/mixer_pipeline.h
+++ b/chromecast/media/cma/backend/mixer/mixer_pipeline.h
@@ -39,6 +39,9 @@
       PostProcessingPipelineFactory* factory,
       int expected_input_channels);
 
+  MixerPipeline(const MixerPipeline&) = delete;
+  MixerPipeline& operator=(const MixerPipeline&) = delete;
+
   ~MixerPipeline();
 
   // Sets the sample rate of all processors.
@@ -100,8 +103,6 @@
   base::flat_map<std::string, FilterGroup*> stream_sinks_;
   FilterGroup* loopback_output_group_ = nullptr;
   FilterGroup* output_group_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(MixerPipeline);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/mixer_service_receiver.cc b/chromecast/media/cma/backend/mixer/mixer_service_receiver.cc
index 2c6f871..6bf2072 100644
--- a/chromecast/media/cma/backend/mixer/mixer_service_receiver.cc
+++ b/chromecast/media/cma/backend/mixer/mixer_service_receiver.cc
@@ -45,6 +45,9 @@
     socket_->SetDelegate(this);
   }
 
+  ControlConnection(const ControlConnection&) = delete;
+  ControlConnection& operator=(const ControlConnection&) = delete;
+
   ~ControlConnection() override = default;
 
   void OnStreamCountChanged() {
@@ -131,8 +134,6 @@
   const std::unique_ptr<mixer_service::MixerSocket> socket_;
 
   bool send_stream_count_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(ControlConnection);
 };
 
 MixerServiceReceiver::MixerServiceReceiver(StreamMixer* mixer,
diff --git a/chromecast/media/cma/backend/mixer/mixer_service_receiver.h b/chromecast/media/cma/backend/mixer/mixer_service_receiver.h
index 70fbf0c..f8e2bf3d 100644
--- a/chromecast/media/cma/backend/mixer/mixer_service_receiver.h
+++ b/chromecast/media/cma/backend/mixer/mixer_service_receiver.h
@@ -24,6 +24,10 @@
 class MixerServiceReceiver : public mixer_service::Receiver {
  public:
   MixerServiceReceiver(StreamMixer* mixer, LoopbackHandler* loopback_handler);
+
+  MixerServiceReceiver(const MixerServiceReceiver&) = delete;
+  MixerServiceReceiver& operator=(const MixerServiceReceiver&) = delete;
+
   ~MixerServiceReceiver() override;
 
   // Called by the mixer when the active stream count changes.
@@ -54,8 +58,6 @@
       control_connections_;
   int primary_stream_count_ = 0;
   int sfx_stream_count_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(MixerServiceReceiver);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/mock_mixer_source.h b/chromecast/media/cma/backend/mixer/mock_mixer_source.h
index 6a6dac03..da1e89c3 100644
--- a/chromecast/media/cma/backend/mixer/mock_mixer_source.h
+++ b/chromecast/media/cma/backend/mixer/mock_mixer_source.h
@@ -30,6 +30,10 @@
   MockMixerSource(int samples_per_second,
                   const std::string& device_id =
                       ::media::AudioDeviceDescription::kDefaultDeviceId);
+
+  MockMixerSource(const MockMixerSource&) = delete;
+  MockMixerSource& operator=(const MockMixerSource&) = delete;
+
   ~MockMixerSource() override;
 
   // MixerInput::Source implementation:
@@ -94,8 +98,6 @@
 
   std::unique_ptr<::media::AudioBus> data_;
   int data_offset_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(MockMixerSource);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/mock_post_processor_factory.h b/chromecast/media/cma/backend/mixer/mock_post_processor_factory.h
index 4dff28a..6bd30de 100644
--- a/chromecast/media/cma/backend/mixer/mock_post_processor_factory.h
+++ b/chromecast/media/cma/backend/mixer/mock_post_processor_factory.h
@@ -28,6 +28,10 @@
                     const std::string& name,
                     const base::Value* filter_description_list,
                     int channels);
+
+  MockPostProcessor(const MockPostProcessor&) = delete;
+  MockPostProcessor& operator=(const MockPostProcessor&) = delete;
+
   ~MockPostProcessor() override;
   MOCK_METHOD5(ProcessFrames,
                double(float* data,
@@ -68,8 +72,6 @@
   bool ringing_ = false;
   float* output_buffer_ = nullptr;
   int num_output_channels_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockPostProcessor);
 };
 
 class MockPostProcessorFactory : public PostProcessingPipelineFactory {
diff --git a/chromecast/media/cma/backend/mixer/mock_redirected_audio_output.h b/chromecast/media/cma/backend/mixer/mock_redirected_audio_output.h
index fb1f88f0..be59bb7d 100644
--- a/chromecast/media/cma/backend/mixer/mock_redirected_audio_output.h
+++ b/chromecast/media/cma/backend/mixer/mock_redirected_audio_output.h
@@ -29,6 +29,11 @@
  public:
   explicit MockRedirectedAudioOutput(
       const mixer_service::RedirectedAudioConnection::Config& config);
+
+  MockRedirectedAudioOutput(const MockRedirectedAudioOutput&) = delete;
+  MockRedirectedAudioOutput& operator=(const MockRedirectedAudioOutput&) =
+      delete;
+
   ~MockRedirectedAudioOutput() override;
 
   ::media::AudioBus* last_buffer() const { return last_buffer_.get(); }
@@ -50,8 +55,6 @@
 
   std::unique_ptr<::media::AudioBus> last_buffer_;
   int64_t last_output_timestamp_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockRedirectedAudioOutput);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/post_processing_pipeline_impl.h b/chromecast/media/cma/backend/mixer/post_processing_pipeline_impl.h
index 869b96ee..0b7226d 100644
--- a/chromecast/media/cma/backend/mixer/post_processing_pipeline_impl.h
+++ b/chromecast/media/cma/backend/mixer/post_processing_pipeline_impl.h
@@ -31,6 +31,11 @@
   PostProcessingPipelineImpl(const std::string& name,
                              const base::Value* filter_description_list,
                              int channels);
+
+  PostProcessingPipelineImpl(const PostProcessingPipelineImpl&) = delete;
+  PostProcessingPipelineImpl& operator=(const PostProcessingPipelineImpl&) =
+      delete;
+
   ~PostProcessingPipelineImpl() override;
 
   double ProcessFrames(float* data,
@@ -83,8 +88,6 @@
   PostProcessorFactory factory_;
 
   std::vector<PostProcessorInfo> processors_;
-
-  DISALLOW_COPY_AND_ASSIGN(PostProcessingPipelineImpl);
 };
 
 class PostProcessingPipelineFactoryImpl : public PostProcessingPipelineFactory {
diff --git a/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h b/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h
index f0e7c64..ecae446a 100644
--- a/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h
+++ b/chromecast/media/cma/backend/mixer/post_processing_pipeline_parser.h
@@ -48,6 +48,10 @@
   // For testing only:
   explicit PostProcessingPipelineParser(base::Value config_dict);
 
+  PostProcessingPipelineParser(const PostProcessingPipelineParser&) = delete;
+  PostProcessingPipelineParser& operator=(const PostProcessingPipelineParser&) =
+      delete;
+
   ~PostProcessingPipelineParser();
 
   std::vector<StreamPipelineDescriptor> GetStreamPipelines();
@@ -66,8 +70,6 @@
   const base::FilePath file_path_;
   base::Value config_dict_;
   const base::Value* postprocessor_config_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(PostProcessingPipelineParser);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/post_processor_factory.h b/chromecast/media/cma/backend/mixer/post_processor_factory.h
index 54b3ffb..8b2f76d 100644
--- a/chromecast/media/cma/backend/mixer/post_processor_factory.h
+++ b/chromecast/media/cma/backend/mixer/post_processor_factory.h
@@ -24,6 +24,10 @@
 class PostProcessorFactory {
  public:
   PostProcessorFactory();
+
+  PostProcessorFactory(const PostProcessorFactory&) = delete;
+  PostProcessorFactory& operator=(const PostProcessorFactory&) = delete;
+
   ~PostProcessorFactory();
 
   // Checks if a library is a V1 or V2 post processor.
@@ -43,8 +47,6 @@
   // Contains all libraries in use;
   // Functions in shared objects cannot be used once library is closed.
   std::vector<std::unique_ptr<base::ScopedNativeLibrary>> libraries_;
-
-  DISALLOW_COPY_AND_ASSIGN(PostProcessorFactory);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/post_processors/governor.h b/chromecast/media/cma/backend/mixer/post_processors/governor.h
index fa8142c..44796d4 100644
--- a/chromecast/media/cma/backend/mixer/post_processors/governor.h
+++ b/chromecast/media/cma/backend/mixer/post_processors/governor.h
@@ -28,6 +28,10 @@
 class Governor : public AudioPostProcessor2 {
  public:
   Governor(const std::string& config, int input_channels);
+
+  Governor(const Governor&) = delete;
+  Governor& operator=(const Governor&) = delete;
+
   ~Governor() override;
 
   // AudioPostProcessor2 implementation:
@@ -46,8 +50,6 @@
   double onset_volume_;
   double clamp_multiplier_;
   SlewVolume slew_volume_;
-
-  DISALLOW_COPY_AND_ASSIGN(Governor);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/post_processors/post_processor_wrapper.h b/chromecast/media/cma/backend/mixer/post_processors/post_processor_wrapper.h
index 4f5268ed..6c91911 100644
--- a/chromecast/media/cma/backend/mixer/post_processors/post_processor_wrapper.h
+++ b/chromecast/media/cma/backend/mixer/post_processors/post_processor_wrapper.h
@@ -34,6 +34,10 @@
   // for owning the lifetime of |pp|. This should only be used for testing.
   AudioPostProcessorWrapper(AudioPostProcessor* pp, int channels);
 
+  AudioPostProcessorWrapper(const AudioPostProcessorWrapper&) = delete;
+  AudioPostProcessorWrapper& operator=(const AudioPostProcessorWrapper&) =
+      delete;
+
   ~AudioPostProcessorWrapper() override;
 
  private:
@@ -48,8 +52,6 @@
   std::unique_ptr<AudioPostProcessor> owned_pp_;
   Status status_;
   AudioPostProcessor* pp_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioPostProcessorWrapper);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/post_processors/saturated_gain.h b/chromecast/media/cma/backend/mixer/post_processors/saturated_gain.h
index 19f5cb5..04e23899 100644
--- a/chromecast/media/cma/backend/mixer/post_processors/saturated_gain.h
+++ b/chromecast/media/cma/backend/mixer/post_processors/saturated_gain.h
@@ -18,6 +18,10 @@
 class SaturatedGain : public AudioPostProcessor2 {
  public:
   SaturatedGain(const std::string& config, int channels);
+
+  SaturatedGain(const SaturatedGain&) = delete;
+  SaturatedGain& operator=(const SaturatedGain&) = delete;
+
   ~SaturatedGain() override;
 
   // AudioPostProcessor implementation:
@@ -31,8 +35,6 @@
   float last_volume_dbfs_;
   SlewVolume slew_volume_;
   float gain_;
-
-  DISALLOW_COPY_AND_ASSIGN(SaturatedGain);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/stream_mixer.h b/chromecast/media/cma/backend/mixer/stream_mixer.h
index 14a95c4..09efccd 100644
--- a/chromecast/media/cma/backend/mixer/stream_mixer.h
+++ b/chromecast/media/cma/backend/mixer/stream_mixer.h
@@ -68,6 +68,10 @@
  public:
   StreamMixer(
       scoped_refptr<base::SequencedTaskRunner> io_task_runner = nullptr);
+
+  StreamMixer(const StreamMixer&) = delete;
+  StreamMixer& operator=(const StreamMixer&) = delete;
+
   ~StreamMixer();
 
   int num_output_channels() const { return num_output_channels_; }
@@ -251,8 +255,6 @@
   base::SequenceBound<MixerServiceReceiver> receiver_;
 
   base::WeakPtrFactory<StreamMixer> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(StreamMixer);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc b/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc
index 9364619..09e9977 100644
--- a/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc
+++ b/chromecast/media/cma/backend/mixer/stream_mixer_unittest.cc
@@ -245,14 +245,16 @@
     : public mixer_service::LoopbackConnection::Delegate {
  public:
   MockLoopbackAudioObserver() = default;
+
+  MockLoopbackAudioObserver(const MockLoopbackAudioObserver&) = delete;
+  MockLoopbackAudioObserver& operator=(const MockLoopbackAudioObserver&) =
+      delete;
+
   ~MockLoopbackAudioObserver() override = default;
 
   MOCK_METHOD6(OnLoopbackAudio,
                void(int64_t, SampleFormat, int, int, uint8_t*, int));
   MOCK_METHOD1(OnLoopbackInterrupted, void(LoopbackInterruptReason));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockLoopbackAudioObserver);
 };
 
 // Given |inputs|, returns mixed audio data according to the mixing method used
diff --git a/chromecast/media/cma/backend/mock_media_pipeline_backend_for_mixer.h b/chromecast/media/cma/backend/mock_media_pipeline_backend_for_mixer.h
index 86620ec..70a1881 100644
--- a/chromecast/media/cma/backend/mock_media_pipeline_backend_for_mixer.h
+++ b/chromecast/media/cma/backend/mock_media_pipeline_backend_for_mixer.h
@@ -32,10 +32,13 @@
   }
 
   int64_t MonotonicClockNow() const override;
-  ~MockMediaPipelineBackendForMixer() override;
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockMediaPipelineBackendForMixer);
+  MockMediaPipelineBackendForMixer(const MockMediaPipelineBackendForMixer&) =
+      delete;
+  MockMediaPipelineBackendForMixer& operator=(
+      const MockMediaPipelineBackendForMixer&) = delete;
+
+  ~MockMediaPipelineBackendForMixer() override;
 };
 
 inline MockMediaPipelineBackendForMixer::~MockMediaPipelineBackendForMixer() =
diff --git a/chromecast/media/cma/backend/multizone_backend_unittest.cc b/chromecast/media/cma/backend/multizone_backend_unittest.cc
index f37ab3c..6bc5bb2 100644
--- a/chromecast/media/cma/backend/multizone_backend_unittest.cc
+++ b/chromecast/media/cma/backend/multizone_backend_unittest.cc
@@ -59,6 +59,10 @@
                base::OnceClosure eos_cb,
                double* rate_change_sequence,
                int num_rate_changes);
+
+  BufferFeeder(const BufferFeeder&) = delete;
+  BufferFeeder& operator=(const BufferFeeder&) = delete;
+
   ~BufferFeeder() override {}
 
   void Initialize();
@@ -120,8 +124,6 @@
   scoped_refptr<DecoderBufferBase> pending_buffer_;
   base::ThreadChecker thread_checker_;
   int current_rate_index_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(BufferFeeder);
 };
 
 double kTestRateSequence1[] = {0.5, 0.7, 0.99, 1.0, 1.01, 1.3, 2.0};
@@ -136,6 +138,10 @@
 class MultizoneBackendTest : public testing::TestWithParam<TestParams> {
  public:
   MultizoneBackendTest();
+
+  MultizoneBackendTest(const MultizoneBackendTest&) = delete;
+  MultizoneBackendTest& operator=(const MultizoneBackendTest&) = delete;
+
   ~MultizoneBackendTest() override;
 
   void SetUp() override {
@@ -164,8 +170,6 @@
   base::test::TaskEnvironment task_environment_;
   std::vector<std::unique_ptr<BufferFeeder>> effects_feeders_;
   std::unique_ptr<BufferFeeder> audio_feeder_;
-
-  DISALLOW_COPY_AND_ASSIGN(MultizoneBackendTest);
 };
 
 namespace {
diff --git a/chromecast/media/cma/backend/proxy/cma_backend_proxy.h b/chromecast/media/cma/backend/proxy/cma_backend_proxy.h
index dd47125..d146060 100644
--- a/chromecast/media/cma/backend/proxy/cma_backend_proxy.h
+++ b/chromecast/media/cma/backend/proxy/cma_backend_proxy.h
@@ -33,6 +33,10 @@
   // to |delegated_video_pipeline|.
   CmaBackendProxy(const MediaPipelineDeviceParams& params,
                   std::unique_ptr<CmaBackend> delegated_video_pipeline);
+
+  CmaBackendProxy(const CmaBackendProxy&) = delete;
+  CmaBackendProxy& operator=(const CmaBackendProxy&) = delete;
+
   ~CmaBackendProxy() override;
 
   // MediaPipelineBackend implementation:
@@ -78,8 +82,6 @@
 
   // The factory to use to populate the |audio_decoder_| object when needed.
   AudioDecoderFactoryCB audio_decoder_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CmaBackendProxy);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/video/av_sync_video.h b/chromecast/media/cma/backend/video/av_sync_video.h
index d0c890b..03998a5c 100644
--- a/chromecast/media/cma/backend/video/av_sync_video.h
+++ b/chromecast/media/cma/backend/video/av_sync_video.h
@@ -23,6 +23,10 @@
 class AvSyncVideo : public AvSync {
  public:
   explicit AvSyncVideo(MediaPipelineBackendForMixer* const backend);
+
+  AvSyncVideo(const AvSyncVideo&) = delete;
+  AvSyncVideo& operator=(const AvSyncVideo&) = delete;
+
   ~AvSyncVideo() override;
 
   // AvSync implementation:
@@ -69,8 +73,6 @@
 
   int64_t last_apts_value_ = INT64_MIN;
   int64_t last_apts_timestamp_ = INT64_MIN;
-
-  DISALLOW_COPY_AND_ASSIGN(AvSyncVideo);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/video_decoder_null.h b/chromecast/media/cma/backend/video_decoder_null.h
index ece5c7b1..836876c 100644
--- a/chromecast/media/cma/backend/video_decoder_null.h
+++ b/chromecast/media/cma/backend/video_decoder_null.h
@@ -17,6 +17,10 @@
 class VideoDecoderNull : public VideoDecoderForMixer {
  public:
   VideoDecoderNull();
+
+  VideoDecoderNull(const VideoDecoderNull&) = delete;
+  VideoDecoderNull& operator=(const VideoDecoderNull&) = delete;
+
   ~VideoDecoderNull() override;
 
   // MediaPipelineBackend::VideoDecoder implementation:
@@ -46,8 +50,6 @@
   Delegate* delegate_;
   Observer* observer_;
   base::WeakPtrFactory<VideoDecoderNull> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoDecoderNull);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/volume_control.cc b/chromecast/media/cma/backend/volume_control.cc
index 0dc9fffe..da26b8a8 100644
--- a/chromecast/media/cma/backend/volume_control.cc
+++ b/chromecast/media/cma/backend/volume_control.cc
@@ -101,6 +101,9 @@
     initialize_complete_event_.Wait();
   }
 
+  VolumeControlInternal(const VolumeControlInternal&) = delete;
+  VolumeControlInternal& operator=(const VolumeControlInternal&) = delete;
+
   ~VolumeControlInternal() override = default;
 
   void AddVolumeObserver(VolumeObserver* observer) {
@@ -372,8 +375,6 @@
   std::unique_ptr<SystemVolumeControl> system_volume_control_;
   std::unique_ptr<mixer_service::ControlConnection> mixer_;
   std::unique_ptr<base::ImportantFileWriter> saved_volumes_writer_;
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeControlInternal);
 };
 
 VolumeControlInternal& GetVolumeControl() {
diff --git a/chromecast/media/cma/backend/volume_map.h b/chromecast/media/cma/backend/volume_map.h
index 9b172ca..fc3fdbd5 100644
--- a/chromecast/media/cma/backend/volume_map.h
+++ b/chromecast/media/cma/backend/volume_map.h
@@ -28,6 +28,9 @@
   // For testing.
   VolumeMap(std::unique_ptr<CastAudioJsonProvider> config_provider);
 
+  VolumeMap(const VolumeMap&) = delete;
+  VolumeMap& operator=(const VolumeMap&) = delete;
+
   ~VolumeMap();
 
   float VolumeToDbFS(float volume);
@@ -50,8 +53,6 @@
   std::vector<LevelToDb> volume_map_;
 
   std::unique_ptr<CastAudioJsonProvider> config_provider_;
-
-  DISALLOW_COPY_AND_ASSIGN(VolumeMap);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/backend/volume_map_unittest.cc b/chromecast/media/cma/backend/volume_map_unittest.cc
index 7e61cee..e0a3b6f 100644
--- a/chromecast/media/cma/backend/volume_map_unittest.cc
+++ b/chromecast/media/cma/backend/volume_map_unittest.cc
@@ -29,6 +29,9 @@
   TestFileProvider(const std::string& file_contents)
       : file_contents_(file_contents) {}
 
+  TestFileProvider(const TestFileProvider&) = delete;
+  TestFileProvider& operator=(const TestFileProvider&) = delete;
+
   ~TestFileProvider() override = default;
 
   void CallTuningChangedCallback(const std::string& new_config) {
@@ -47,8 +50,6 @@
 
   const std::string file_contents_;
   TuningChangedCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestFileProvider);
 };
 
 TEST(VolumeMapTest, UsesDefaultMapIfConfigEmpty) {
diff --git a/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc b/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
index b320a59..e65af6e 100644
--- a/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
+++ b/chromecast/media/cma/base/balanced_media_task_runner_unittest.cc
@@ -53,6 +53,11 @@
 class BalancedMediaTaskRunnerTest : public testing::Test {
  public:
   BalancedMediaTaskRunnerTest();
+
+  BalancedMediaTaskRunnerTest(const BalancedMediaTaskRunnerTest&) = delete;
+  BalancedMediaTaskRunnerTest& operator=(const BalancedMediaTaskRunnerTest&) =
+      delete;
+
   ~BalancedMediaTaskRunnerTest() override;
 
   void SetupTest(base::TimeDelta max_delta,
@@ -82,8 +87,6 @@
   // For each media task runner, keep a track of which task has already been
   // scheduled.
   std::vector<MediaTaskRunnerTestContext> contexts_;
-
-  DISALLOW_COPY_AND_ASSIGN(BalancedMediaTaskRunnerTest);
 };
 
 BalancedMediaTaskRunnerTest::BalancedMediaTaskRunnerTest() {
diff --git a/chromecast/media/cma/base/buffering_controller.h b/chromecast/media/cma/base/buffering_controller.h
index dfa927b..a30f9cf9 100644
--- a/chromecast/media/cma/base/buffering_controller.h
+++ b/chromecast/media/cma/base/buffering_controller.h
@@ -34,6 +34,10 @@
   BufferingController(
       const scoped_refptr<BufferingConfig>& config,
       const BufferingNotificationCB& buffering_notification_cb);
+
+  BufferingController(const BufferingController&) = delete;
+  BufferingController& operator=(const BufferingController&) = delete;
+
   ~BufferingController();
 
   // Creates a buffering state for one stream. This state is added to the list
@@ -106,8 +110,6 @@
 
   base::WeakPtr<BufferingController> weak_this_;
   base::WeakPtrFactory<BufferingController> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BufferingController);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/base/buffering_frame_provider.h b/chromecast/media/cma/base/buffering_frame_provider.h
index 470b8e2..befc9e3b 100644
--- a/chromecast/media/cma/base/buffering_frame_provider.h
+++ b/chromecast/media/cma/base/buffering_frame_provider.h
@@ -44,6 +44,10 @@
       size_t max_buffer_size,
       size_t max_frame_size,
       const FrameBufferedCB& frame_buffered_cb);
+
+  BufferingFrameProvider(const BufferingFrameProvider&) = delete;
+  BufferingFrameProvider& operator=(const BufferingFrameProvider&) = delete;
+
   ~BufferingFrameProvider() override;
 
   // CodedFrameProvider implementation.
@@ -112,8 +116,6 @@
 
   base::WeakPtr<BufferingFrameProvider> weak_this_;
   base::WeakPtrFactory<BufferingFrameProvider> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BufferingFrameProvider);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/base/buffering_frame_provider_unittest.cc b/chromecast/media/cma/base/buffering_frame_provider_unittest.cc
index 26522a5..74596a7 100644
--- a/chromecast/media/cma/base/buffering_frame_provider_unittest.cc
+++ b/chromecast/media/cma/base/buffering_frame_provider_unittest.cc
@@ -36,6 +36,11 @@
 class BufferingFrameProviderTest : public testing::Test {
  public:
   BufferingFrameProviderTest();
+
+  BufferingFrameProviderTest(const BufferingFrameProviderTest&) = delete;
+  BufferingFrameProviderTest& operator=(const BufferingFrameProviderTest&) =
+      delete;
+
   ~BufferingFrameProviderTest() override;
 
   // Setup the test.
@@ -54,8 +59,6 @@
  private:
   void OnTestTimeout();
   void OnTestCompleted();
-
-  DISALLOW_COPY_AND_ASSIGN(BufferingFrameProviderTest);
 };
 
 BufferingFrameProviderTest::BufferingFrameProviderTest() {
diff --git a/chromecast/media/cma/base/coded_frame_provider.h b/chromecast/media/cma/base/coded_frame_provider.h
index 1281a9c..77e0e4cf 100644
--- a/chromecast/media/cma/base/coded_frame_provider.h
+++ b/chromecast/media/cma/base/coded_frame_provider.h
@@ -26,6 +26,10 @@
       ReadCB;
 
   CodedFrameProvider();
+
+  CodedFrameProvider(const CodedFrameProvider&) = delete;
+  CodedFrameProvider& operator=(const CodedFrameProvider&) = delete;
+
   virtual ~CodedFrameProvider();
 
   // Request a coded frame which is provided asynchronously through callback
@@ -42,9 +46,6 @@
   // callback will not be invoked.
   // TODO(alokp): Delete this function once CmaRenderer is deprecated.
   virtual void Flush(base::OnceClosure flush_cb) = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(CodedFrameProvider);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/base/demuxer_stream_adapter.h b/chromecast/media/cma/base/demuxer_stream_adapter.h
index fdf9103..5a815d8 100644
--- a/chromecast/media/cma/base/demuxer_stream_adapter.h
+++ b/chromecast/media/cma/base/demuxer_stream_adapter.h
@@ -36,6 +36,10 @@
       const scoped_refptr<BalancedMediaTaskRunnerFactory>&
           media_task_runner_factory,
       ::media::DemuxerStream* demuxer_stream);
+
+  DemuxerStreamAdapter(const DemuxerStreamAdapter&) = delete;
+  DemuxerStreamAdapter& operator=(const DemuxerStreamAdapter&) = delete;
+
   ~DemuxerStreamAdapter() override;
 
   // CodedFrameProvider implementation.
@@ -83,8 +87,6 @@
 
   base::WeakPtr<DemuxerStreamAdapter> weak_this_;
   base::WeakPtrFactory<DemuxerStreamAdapter> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(DemuxerStreamAdapter);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/base/demuxer_stream_adapter_unittest.cc b/chromecast/media/cma/base/demuxer_stream_adapter_unittest.cc
index 3efc1e5..49e79ac6 100644
--- a/chromecast/media/cma/base/demuxer_stream_adapter_unittest.cc
+++ b/chromecast/media/cma/base/demuxer_stream_adapter_unittest.cc
@@ -34,6 +34,10 @@
 class DemuxerStreamAdapterTest : public testing::Test {
  public:
   DemuxerStreamAdapterTest();
+
+  DemuxerStreamAdapterTest(const DemuxerStreamAdapterTest&) = delete;
+  DemuxerStreamAdapterTest& operator=(const DemuxerStreamAdapterTest&) = delete;
+
   ~DemuxerStreamAdapterTest() override;
 
   void Initialize(::media::DemuxerStream* demuxer_stream);
@@ -65,8 +69,6 @@
   std::unique_ptr<DemuxerStreamForTest> demuxer_stream_;
 
   std::unique_ptr<CodedFrameProvider> coded_frame_provider_;
-
-  DISALLOW_COPY_AND_ASSIGN(DemuxerStreamAdapterTest);
 };
 
 DemuxerStreamAdapterTest::DemuxerStreamAdapterTest()
diff --git a/chromecast/media/cma/base/demuxer_stream_for_test.h b/chromecast/media/cma/base/demuxer_stream_for_test.h
index 64f862c..0352ce0 100644
--- a/chromecast/media/cma/base/demuxer_stream_for_test.h
+++ b/chromecast/media/cma/base/demuxer_stream_for_test.h
@@ -38,6 +38,10 @@
                        int cycle_count,
                        int delayed_frame_count,
                        const std::list<int>& config_idx);
+
+  DemuxerStreamForTest(const DemuxerStreamForTest&) = delete;
+  DemuxerStreamForTest& operator=(const DemuxerStreamForTest&) = delete;
+
   ~DemuxerStreamForTest() override;
 
   // ::media::DemuxerStream implementation.
@@ -61,8 +65,6 @@
 
   // Number of frames sent so far.
   int frame_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(DemuxerStreamForTest);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/base/multi_demuxer_stream_adapter_unittest.cc b/chromecast/media/cma/base/multi_demuxer_stream_adapter_unittest.cc
index 47f70d0f..8310707a9 100644
--- a/chromecast/media/cma/base/multi_demuxer_stream_adapter_unittest.cc
+++ b/chromecast/media/cma/base/multi_demuxer_stream_adapter_unittest.cc
@@ -37,6 +37,12 @@
 class MultiDemuxerStreamAdaptersTest : public testing::Test {
  public:
   MultiDemuxerStreamAdaptersTest();
+
+  MultiDemuxerStreamAdaptersTest(const MultiDemuxerStreamAdaptersTest&) =
+      delete;
+  MultiDemuxerStreamAdaptersTest& operator=(
+      const MultiDemuxerStreamAdaptersTest&) = delete;
+
   ~MultiDemuxerStreamAdaptersTest() override;
 
   void Start();
@@ -69,7 +75,6 @@
   int running_stream_count_;
 
   scoped_refptr<BalancedMediaTaskRunnerFactory> media_task_runner_factory_;
-  DISALLOW_COPY_AND_ASSIGN(MultiDemuxerStreamAdaptersTest);
 };
 
 MultiDemuxerStreamAdaptersTest::MultiDemuxerStreamAdaptersTest() {
diff --git a/chromecast/media/cma/pipeline/audio_pipeline_impl.h b/chromecast/media/cma/pipeline/audio_pipeline_impl.h
index aafe74b..01937a1e 100644
--- a/chromecast/media/cma/pipeline/audio_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/audio_pipeline_impl.h
@@ -27,6 +27,10 @@
 class AudioPipelineImpl : public AvPipelineImpl {
  public:
   AudioPipelineImpl(CmaBackend::AudioDecoder* decoder, AvPipelineClient client);
+
+  AudioPipelineImpl(const AudioPipelineImpl&) = delete;
+  AudioPipelineImpl& operator=(const AudioPipelineImpl&) = delete;
+
   ~AudioPipelineImpl() override;
 
   ::media::PipelineStatus Initialize(
@@ -49,8 +53,6 @@
   CmaBackend::AudioDecoder* const audio_decoder_;
 
   EncryptionScheme encryption_scheme_ = EncryptionScheme::kUnencrypted;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioPipelineImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/pipeline/av_pipeline_impl.h b/chromecast/media/cma/pipeline/av_pipeline_impl.h
index 9f48385..bbcc257 100644
--- a/chromecast/media/cma/pipeline/av_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/av_pipeline_impl.h
@@ -42,6 +42,10 @@
 class AvPipelineImpl : CmaBackend::Decoder::Delegate {
  public:
   AvPipelineImpl(CmaBackend::Decoder* decoder, AvPipelineClient client);
+
+  AvPipelineImpl(const AvPipelineImpl&) = delete;
+  AvPipelineImpl& operator=(const AvPipelineImpl&) = delete;
+
   ~AvPipelineImpl() override;
 
   void SetCdm(CastCdmContext* cast_cdm_context);
@@ -194,8 +198,6 @@
   // cancel pending asynchronous decryption (by invalidating this factory's weak
   // ptrs) without affecting other bound callbacks.
   base::WeakPtrFactory<AvPipelineImpl> decrypt_weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(AvPipelineImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/pipeline/backend_decryptor.h b/chromecast/media/cma/pipeline/backend_decryptor.h
index ddb6d36f..05faea2 100644
--- a/chromecast/media/cma/pipeline/backend_decryptor.h
+++ b/chromecast/media/cma/pipeline/backend_decryptor.h
@@ -24,6 +24,10 @@
                          MediaPipelineBackend::AudioDecryptor::Delegate {
  public:
   explicit BackendDecryptor(EncryptionScheme scheme);
+
+  BackendDecryptor(const BackendDecryptor&) = delete;
+  BackendDecryptor& operator=(const BackendDecryptor&) = delete;
+
   ~BackendDecryptor() override;
 
   // StreamDecryptor implementation:
@@ -49,8 +53,6 @@
   std::unique_ptr<MediaPipelineBackend::AudioDecryptor> decryptor_;
 
   DecryptCB decrypt_cb_;
-
-  DISALLOW_COPY_AND_ASSIGN(BackendDecryptor);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/pipeline/cdm_decryptor.h b/chromecast/media/cma/pipeline/cdm_decryptor.h
index f822000..ef1eb13 100644
--- a/chromecast/media/cma/pipeline/cdm_decryptor.h
+++ b/chromecast/media/cma/pipeline/cdm_decryptor.h
@@ -15,6 +15,10 @@
 class CdmDecryptor : public StreamDecryptor {
  public:
   explicit CdmDecryptor(bool clear_buffer_needed);
+
+  CdmDecryptor(const CdmDecryptor&) = delete;
+  CdmDecryptor& operator=(const CdmDecryptor&) = delete;
+
   ~CdmDecryptor() override;
 
   // StreamDecryptor implementation:
@@ -30,7 +34,6 @@
 
   base::WeakPtr<CdmDecryptor> weak_this_;
   base::WeakPtrFactory<CdmDecryptor> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(CdmDecryptor);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/pipeline/media_pipeline_impl.h b/chromecast/media/cma/pipeline/media_pipeline_impl.h
index 56cae1a..6cf781e 100644
--- a/chromecast/media/cma/pipeline/media_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/media_pipeline_impl.h
@@ -37,6 +37,10 @@
 class MediaPipelineImpl {
  public:
   MediaPipelineImpl();
+
+  MediaPipelineImpl(const MediaPipelineImpl&) = delete;
+  MediaPipelineImpl& operator=(const MediaPipelineImpl&) = delete;
+
   ~MediaPipelineImpl();
 
   // Initialize the media pipeline: the pipeline is configured based on
@@ -132,8 +136,6 @@
 
   base::WeakPtr<MediaPipelineImpl> weak_this_;
   base::WeakPtrFactory<MediaPipelineImpl> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaPipelineImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/pipeline/video_pipeline_impl.h b/chromecast/media/cma/pipeline/video_pipeline_impl.h
index 43dfc753..234bbfe8 100644
--- a/chromecast/media/cma/pipeline/video_pipeline_impl.h
+++ b/chromecast/media/cma/pipeline/video_pipeline_impl.h
@@ -29,6 +29,10 @@
  public:
   VideoPipelineImpl(CmaBackend::VideoDecoder* decoder,
                     VideoPipelineClient client);
+
+  VideoPipelineImpl(const VideoPipelineImpl&) = delete;
+  VideoPipelineImpl& operator=(const VideoPipelineImpl&) = delete;
+
   ~VideoPipelineImpl() override;
 
   ::media::PipelineStatus Initialize(
@@ -50,8 +54,6 @@
   CmaBackend::VideoDecoder* const video_decoder_;
   const VideoPipelineClient::NaturalSizeChangedCB natural_size_changed_cb_;
   std::vector<EncryptionScheme> encryption_schemes_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoPipelineImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/test/frame_generator_for_test.h b/chromecast/media/cma/test/frame_generator_for_test.h
index a2e8f2c..c473a6a 100644
--- a/chromecast/media/cma/test/frame_generator_for_test.h
+++ b/chromecast/media/cma/test/frame_generator_for_test.h
@@ -34,6 +34,10 @@
   };
 
   explicit FrameGeneratorForTest(const std::vector<FrameSpec> frame_specs);
+
+  FrameGeneratorForTest(const FrameGeneratorForTest&) = delete;
+  FrameGeneratorForTest& operator=(const FrameGeneratorForTest&) = delete;
+
   ~FrameGeneratorForTest();
 
   // Indicates whether the next frame should come with a new decoder config.
@@ -52,8 +56,6 @@
 
   // Total size of A/V buffers generated so far.
   size_t total_buffer_size_;
-
-  DISALLOW_COPY_AND_ASSIGN(FrameGeneratorForTest);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/test/mock_frame_consumer.h b/chromecast/media/cma/test/mock_frame_consumer.h
index 991a818..32a62c28 100644
--- a/chromecast/media/cma/test/mock_frame_consumer.h
+++ b/chromecast/media/cma/test/mock_frame_consumer.h
@@ -27,6 +27,10 @@
 class MockFrameConsumer {
  public:
   explicit MockFrameConsumer(CodedFrameProvider* coded_frame_provider);
+
+  MockFrameConsumer(const MockFrameConsumer&) = delete;
+  MockFrameConsumer& operator=(const MockFrameConsumer&) = delete;
+
   ~MockFrameConsumer();
 
   void Configure(const std::vector<bool>& delayed_task_pattern,
@@ -62,8 +66,6 @@
 
   // Expected results.
   std::unique_ptr<FrameGeneratorForTest> frame_generator_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockFrameConsumer);
 };
 
 }  // namespace media
diff --git a/chromecast/media/cma/test/mock_frame_provider.h b/chromecast/media/cma/test/mock_frame_provider.h
index 0ec7188..0efdbf83 100644
--- a/chromecast/media/cma/test/mock_frame_provider.h
+++ b/chromecast/media/cma/test/mock_frame_provider.h
@@ -20,6 +20,10 @@
 class MockFrameProvider : public CodedFrameProvider {
  public:
   MockFrameProvider();
+
+  MockFrameProvider(const MockFrameProvider&) = delete;
+  MockFrameProvider& operator=(const MockFrameProvider&) = delete;
+
   ~MockFrameProvider() override;
 
   void Configure(const std::vector<bool>& delayed_task_pattern,
@@ -45,8 +49,6 @@
   bool delay_flush_;
 
   std::unique_ptr<FrameGeneratorForTest> frame_generator_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockFrameProvider);
 };
 
 }  // namespace media
diff --git a/chromecast/media/common/audio_decoder_software_wrapper.h b/chromecast/media/common/audio_decoder_software_wrapper.h
index cc3b7c6..2b608ce 100644
--- a/chromecast/media/common/audio_decoder_software_wrapper.h
+++ b/chromecast/media/common/audio_decoder_software_wrapper.h
@@ -29,6 +29,11 @@
 
   AudioDecoderSoftwareWrapper(
       MediaPipelineBackend::AudioDecoder* backend_decoder);
+
+  AudioDecoderSoftwareWrapper(const AudioDecoderSoftwareWrapper&) = delete;
+  AudioDecoderSoftwareWrapper& operator=(const AudioDecoderSoftwareWrapper&) =
+      delete;
+
   ~AudioDecoderSoftwareWrapper() override;
 
   void SetDelegate(DecoderDelegate* delegate);
@@ -60,8 +65,6 @@
   AudioConfig output_config_;
   scoped_refptr<DecoderBufferBase> pending_pushed_buffer_;
   bool decoder_error_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioDecoderSoftwareWrapper);
 };
 
 }  // namespace media
diff --git a/chromecast/media/common/audio_decoder_wrapper.cc b/chromecast/media/common/audio_decoder_wrapper.cc
index 0265be5..92f0c9b0 100644
--- a/chromecast/media/common/audio_decoder_wrapper.cc
+++ b/chromecast/media/common/audio_decoder_wrapper.cc
@@ -27,6 +27,11 @@
       : rendering_delay_(rendering_delay),
         statistics_(statistics),
         requires_decryption_(requires_decryption) {}
+
+  RevokedAudioDecoderWrapper(const RevokedAudioDecoderWrapper&) = delete;
+  RevokedAudioDecoderWrapper& operator=(const RevokedAudioDecoderWrapper&) =
+      delete;
+
   ~RevokedAudioDecoderWrapper() override = default;
 
  private:
@@ -48,8 +53,6 @@
   const RenderingDelay rendering_delay_;
   const Statistics statistics_;
   const bool requires_decryption_;
-
-  DISALLOW_COPY_AND_ASSIGN(RevokedAudioDecoderWrapper);
 };
 
 }  // namespace
diff --git a/chromecast/media/common/audio_decoder_wrapper.h b/chromecast/media/common/audio_decoder_wrapper.h
index 0e76bd9..a01b809 100644
--- a/chromecast/media/common/audio_decoder_wrapper.h
+++ b/chromecast/media/common/audio_decoder_wrapper.h
@@ -33,6 +33,11 @@
       MediaPipelineBackend::AudioDecoder* backend_decoder,
       AudioContentType type,
       MediaPipelineBackendManager::BufferDelegate* buffer_delegate);
+
+  ActiveAudioDecoderWrapper(const ActiveAudioDecoderWrapper&) = delete;
+  ActiveAudioDecoderWrapper& operator=(const ActiveAudioDecoderWrapper&) =
+      delete;
+
   ~ActiveAudioDecoderWrapper() override;
 
   AudioContentType content_type() const { return content_type_; }
@@ -59,8 +64,6 @@
   float stream_volume_multiplier_;
 
   scoped_refptr<DecoderBufferBase> pushed_buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(ActiveAudioDecoderWrapper);
 };
 
 class AudioDecoderWrapper : public CmaBackend::AudioDecoder {
@@ -72,6 +75,10 @@
       MediaPipelineBackendManager::BufferDelegate* buffer_delegate);
   // Create a "fake" AudioDecoder that's already in revoked state.
   AudioDecoderWrapper(AudioContentType type);
+
+  AudioDecoderWrapper(const AudioDecoderWrapper&) = delete;
+  AudioDecoderWrapper& operator=(const AudioDecoderWrapper&) = delete;
+
   ~AudioDecoderWrapper() override;
 
   void OnInitialized();
@@ -91,8 +98,6 @@
   bool decoder_revoked_;
 
   std::unique_ptr<DestructableAudioDecoder> audio_decoder_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioDecoderWrapper);
 };
 
 }  // namespace media
diff --git a/chromecast/media/common/media_pipeline_backend_wrapper.cc b/chromecast/media/common/media_pipeline_backend_wrapper.cc
index b80a9fe0..d9060f5 100644
--- a/chromecast/media/common/media_pipeline_backend_wrapper.cc
+++ b/chromecast/media/common/media_pipeline_backend_wrapper.cc
@@ -34,6 +34,11 @@
                                      int64_t current_pts)
       : content_type_(content_type), current_pts_(current_pts) {}
 
+  RevokedMediaPipelineBackendWrapper(
+      const RevokedMediaPipelineBackendWrapper&) = delete;
+  RevokedMediaPipelineBackendWrapper& operator=(
+      const RevokedMediaPipelineBackendWrapper&) = delete;
+
   ~RevokedMediaPipelineBackendWrapper() override = default;
 
   std::unique_ptr<AudioDecoderWrapper> CreateAudioDecoderWrapper() override {
@@ -68,8 +73,6 @@
  private:
   const AudioContentType content_type_;
   const int64_t current_pts_;
-
-  DISALLOW_COPY_AND_ASSIGN(RevokedMediaPipelineBackendWrapper);
 };
 
 }  // namespace
@@ -81,6 +84,12 @@
       MediaPipelineBackendWrapper* wrapping_backend,
       MediaPipelineBackendManager* backend_manager,
       MediaResourceTracker* media_resource_tracker);
+
+  ActiveMediaPipelineBackendWrapper(const ActiveMediaPipelineBackendWrapper&) =
+      delete;
+  ActiveMediaPipelineBackendWrapper& operator=(
+      const ActiveMediaPipelineBackendWrapper&) = delete;
+
   ~ActiveMediaPipelineBackendWrapper() override;
 
   // DecoderCreatorCmaBackend implementation:
@@ -122,8 +131,6 @@
   MediaResourceTracker::ScopedUsage media_resource_usage_;
 
   bool playing_;
-
-  DISALLOW_COPY_AND_ASSIGN(ActiveMediaPipelineBackendWrapper);
 };
 
 ActiveMediaPipelineBackendWrapper::ActiveMediaPipelineBackendWrapper(
diff --git a/chromecast/media/common/media_pipeline_backend_wrapper.h b/chromecast/media/common/media_pipeline_backend_wrapper.h
index 75d21e5..71e5b81 100644
--- a/chromecast/media/common/media_pipeline_backend_wrapper.h
+++ b/chromecast/media/common/media_pipeline_backend_wrapper.h
@@ -30,6 +30,11 @@
   MediaPipelineBackendWrapper(const media::MediaPipelineDeviceParams& params,
                               MediaPipelineBackendManager* backend_manager,
                               MediaResourceTracker* media_resource_tracker);
+
+  MediaPipelineBackendWrapper(const MediaPipelineBackendWrapper&) = delete;
+  MediaPipelineBackendWrapper& operator=(const MediaPipelineBackendWrapper&) =
+      delete;
+
   ~MediaPipelineBackendWrapper() override;
 
   // After revocation, this class releases the media resource on the device,
@@ -58,8 +63,6 @@
   std::unique_ptr<DecoderCreatorCmaBackend> backend_;
   MediaPipelineBackendManager* const backend_manager_;
   const AudioContentType content_type_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaPipelineBackendWrapper);
 };
 
 }  // namespace media
diff --git a/chromecast/media/common/media_resource_tracker.h b/chromecast/media/common/media_resource_tracker.h
index 46e4924..38dfa9f 100644
--- a/chromecast/media/common/media_resource_tracker.h
+++ b/chromecast/media/common/media_resource_tracker.h
@@ -40,11 +40,14 @@
   class ScopedUsage {
    public:
     ScopedUsage(MediaResourceTracker* tracker);
+
+    ScopedUsage(const ScopedUsage&) = delete;
+    ScopedUsage& operator=(const ScopedUsage&) = delete;
+
     ~ScopedUsage();
 
    private:
     MediaResourceTracker* tracker_;
-    DISALLOW_COPY_AND_ASSIGN(ScopedUsage);
   };
 
   MediaResourceTracker(
diff --git a/chromecast/media/common/media_resource_tracker_unittest.cc b/chromecast/media/common/media_resource_tracker_unittest.cc
index 26c0d72..32ea212 100644
--- a/chromecast/media/common/media_resource_tracker_unittest.cc
+++ b/chromecast/media/common/media_resource_tracker_unittest.cc
@@ -19,6 +19,10 @@
 class MediaResourceTrackerTest : public ::testing::Test {
  public:
   MediaResourceTrackerTest() {}
+
+  MediaResourceTrackerTest(const MediaResourceTrackerTest&) = delete;
+  MediaResourceTrackerTest& operator=(const MediaResourceTrackerTest&) = delete;
+
   ~MediaResourceTrackerTest() override {}
 
  protected:
@@ -39,8 +43,6 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
   TestMediaResourceTracker* resource_tracker_;
   std::unique_ptr<MediaResourceTrackerTestMocks> test_mocks_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaResourceTrackerTest);
 };
 
 TEST_F(MediaResourceTrackerTest, BasicLifecycle) {
diff --git a/chromecast/media/common/test_media_resource_tracker.h b/chromecast/media/common/test_media_resource_tracker.h
index 1a691ab..7633b5b 100644
--- a/chromecast/media/common/test_media_resource_tracker.h
+++ b/chromecast/media/common/test_media_resource_tracker.h
@@ -34,6 +34,9 @@
       scoped_refptr<base::SingleThreadTaskRunner> media_task_runner,
       MediaResourceTrackerTestMocks* test_mocks);
 
+  TestMediaResourceTracker(const TestMediaResourceTracker&) = delete;
+  TestMediaResourceTracker& operator=(const TestMediaResourceTracker&) = delete;
+
   ~TestMediaResourceTracker() override;
 
   size_t media_use_count() const { return media_use_count_; }
@@ -44,8 +47,6 @@
   void DoFinalizeMediaLib() override;
 
   MediaResourceTrackerTestMocks* const test_mocks_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestMediaResourceTracker);
 };
 
 }  // namespace media
diff --git a/chromecast/media/common/video_decoder_wrapper.cc b/chromecast/media/common/video_decoder_wrapper.cc
index 24606e5..5fb8239 100644
--- a/chromecast/media/common/video_decoder_wrapper.cc
+++ b/chromecast/media/common/video_decoder_wrapper.cc
@@ -19,6 +19,9 @@
   explicit RevokedVideoDecoder(const Statistics& statistics)
       : statistics_(statistics) {}
 
+  RevokedVideoDecoder(const RevokedVideoDecoder&) = delete;
+  RevokedVideoDecoder& operator=(const RevokedVideoDecoder&) = delete;
+
   ~RevokedVideoDecoder() override = default;
 
  private:
@@ -36,7 +39,6 @@
   }
 
   Statistics statistics_;
-  DISALLOW_COPY_AND_ASSIGN(RevokedVideoDecoder);
 };
 
 VideoDecoderWrapper::VideoDecoderWrapper(
diff --git a/chromecast/media/common/video_decoder_wrapper.h b/chromecast/media/common/video_decoder_wrapper.h
index ef094010..85f6210 100644
--- a/chromecast/media/common/video_decoder_wrapper.h
+++ b/chromecast/media/common/video_decoder_wrapper.h
@@ -24,6 +24,9 @@
   // Create a VideoDecoderWrapper that's already been revoked.
   VideoDecoderWrapper();
 
+  VideoDecoderWrapper(const VideoDecoderWrapper&) = delete;
+  VideoDecoderWrapper& operator=(const VideoDecoderWrapper&) = delete;
+
   ~VideoDecoderWrapper() override;
 
   void Revoke();
@@ -41,8 +44,6 @@
 
   MediaPipelineBackend::VideoDecoder* decoder_;
   std::unique_ptr<RevokedVideoDecoder> revoked_video_decoder_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoDecoderWrapper);
 };
 
 }  // namespace media
diff --git a/chromecast/media/service/cast_mojo_media_client.h b/chromecast/media/service/cast_mojo_media_client.h
index 0fbdecd..b98de47b 100644
--- a/chromecast/media/service/cast_mojo_media_client.h
+++ b/chromecast/media/service/cast_mojo_media_client.h
@@ -32,6 +32,10 @@
                       VideoModeSwitcher* video_mode_switcher,
                       VideoResolutionPolicy* video_resolution_policy,
                       external_service_support::ExternalConnector* connector);
+
+  CastMojoMediaClient(const CastMojoMediaClient&) = delete;
+  CastMojoMediaClient& operator=(const CastMojoMediaClient&) = delete;
+
   ~CastMojoMediaClient() override;
 
 #if BUILDFLAG(ENABLE_CAST_RENDERER)
@@ -65,8 +69,6 @@
 #if BUILDFLAG(ENABLE_CAST_RENDERER)
   VideoGeometrySetterService* video_geometry_setter_;
 #endif
-
-  DISALLOW_COPY_AND_ASSIGN(CastMojoMediaClient);
 };
 
 }  // namespace media
diff --git a/chromecast/media/service/cast_renderer.h b/chromecast/media/service/cast_renderer.h
index 53fa8dd..b505ea2 100644
--- a/chromecast/media/service/cast_renderer.h
+++ b/chromecast/media/service/cast_renderer.h
@@ -52,6 +52,10 @@
                const base::UnguessableToken& overlay_plane_id,
                ::media::mojom::FrameInterfaceFactory* frame_interfaces,
                external_service_support::ExternalConnector* connector);
+
+  CastRenderer(const CastRenderer&) = delete;
+  CastRenderer& operator=(const CastRenderer&) = delete;
+
   ~CastRenderer() override;
   // For CmaBackend implementation, CastRenderer must be connected to
   // VideoGeometrySetterService.
@@ -147,7 +151,6 @@
   absl::optional<float> pending_volume_;
 
   base::WeakPtrFactory<CastRenderer> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(CastRenderer);
 };
 
 }  // namespace media
diff --git a/chromecast/media/service/video_geometry_setter_service.h b/chromecast/media/service/video_geometry_setter_service.h
index 5a276cd5..5e82df24 100644
--- a/chromecast/media/service/video_geometry_setter_service.h
+++ b/chromecast/media/service/video_geometry_setter_service.h
@@ -31,6 +31,11 @@
       public mojom::VideoGeometrySetter {
  public:
   VideoGeometrySetterService();
+
+  VideoGeometrySetterService(const VideoGeometrySetterService&) = delete;
+  VideoGeometrySetterService& operator=(const VideoGeometrySetterService&) =
+      delete;
+
   ~VideoGeometrySetterService() override;
 
   void GetVideoGeometryChangeSubscriber(
@@ -67,7 +72,6 @@
       this};
 
   base::WeakPtrFactory<VideoGeometrySetterService> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(VideoGeometrySetterService);
 };
 
 }  // namespace media
diff --git a/chromecast/metrics/cast_metrics_service_client.cc b/chromecast/metrics/cast_metrics_service_client.cc
index 60b4bdb..627abcf 100644
--- a/chromecast/metrics/cast_metrics_service_client.cc
+++ b/chromecast/metrics/cast_metrics_service_client.cc
@@ -319,8 +319,7 @@
   // exists, the entropy provider type is unused.
   // TODO(crbug/1249485): Make Chromecast consistent with other platforms. I.e.
   // create the FieldTrialList and the MetricsStateManager around the same time.
-  metrics_state_manager_->InstantiateFieldTrialList(
-      ::metrics::EntropyProviderType::kDefault);
+  metrics_state_manager_->InstantiateFieldTrialList();
 
   metrics_service_.reset(new ::metrics::MetricsService(
       metrics_state_manager_.get(), this, pref_service_));
diff --git a/chromecast/net/fake_stream_socket.cc b/chromecast/net/fake_stream_socket.cc
index 05d558b..6234504 100644
--- a/chromecast/net/fake_stream_socket.cc
+++ b/chromecast/net/fake_stream_socket.cc
@@ -25,6 +25,10 @@
 class SocketBuffer {
  public:
   SocketBuffer() : pending_read_data_(nullptr), pending_read_len_(0) {}
+
+  SocketBuffer(const SocketBuffer&) = delete;
+  SocketBuffer& operator=(const SocketBuffer&) = delete;
+
   ~SocketBuffer() {}
 
   // Reads |len| bytes from the buffer and writes it to |data|. Returns the
@@ -99,8 +103,6 @@
   net::CompletionOnceCallback pending_read_callback_;
   bool eos_ = false;
   base::WeakPtrFactory<SocketBuffer> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(SocketBuffer);
 };
 
 FakeStreamSocket::FakeStreamSocket() : FakeStreamSocket(net::IPEndPoint()) {}
diff --git a/chromecast/net/fake_stream_socket.h b/chromecast/net/fake_stream_socket.h
index 8c1bcbc..d503f740 100644
--- a/chromecast/net/fake_stream_socket.h
+++ b/chromecast/net/fake_stream_socket.h
@@ -23,6 +23,10 @@
  public:
   FakeStreamSocket();
   explicit FakeStreamSocket(const net::IPEndPoint& local_address);
+
+  FakeStreamSocket(const FakeStreamSocket&) = delete;
+  FakeStreamSocket& operator=(const FakeStreamSocket&) = delete;
+
   ~FakeStreamSocket() override;
 
   // Sets the peer for this socket.
@@ -68,8 +72,6 @@
   FakeStreamSocket* peer_;
   net::NetLogWithSource net_log_;
   bool bad_sender_mode_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeStreamSocket);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/net/io_buffer_pool.cc b/chromecast/net/io_buffer_pool.cc
index 5918277..15e9887 100644
--- a/chromecast/net/io_buffer_pool.cc
+++ b/chromecast/net/io_buffer_pool.cc
@@ -103,6 +103,9 @@
   Wrapper(char* data, IOBufferPool::Internal* pool)
       : buffer_(data), pool_(pool) {}
 
+  Wrapper(const Wrapper&) = delete;
+  Wrapper& operator=(const Wrapper&) = delete;
+
   ~Wrapper() = delete;
   static void operator delete(void*) = delete;
 
@@ -113,8 +116,6 @@
  private:
   Buffer buffer_;
   IOBufferPool::Internal* const pool_;
-
-  DISALLOW_COPY_AND_ASSIGN(Wrapper);
 };
 
 union IOBufferPool::Internal::Storage {
diff --git a/chromecast/net/mock_stream_socket.h b/chromecast/net/mock_stream_socket.h
index 951d353..3bc156d 100644
--- a/chromecast/net/mock_stream_socket.h
+++ b/chromecast/net/mock_stream_socket.h
@@ -20,6 +20,10 @@
 class MockStreamSocket : public net::StreamSocket {
  public:
   MockStreamSocket();
+
+  MockStreamSocket(const MockStreamSocket&) = delete;
+  MockStreamSocket& operator=(const MockStreamSocket&) = delete;
+
   ~MockStreamSocket() override;
 
   MOCK_METHOD3(Read, int(net::IOBuffer*, int, net::CompletionOnceCallback));
@@ -50,8 +54,6 @@
 
  private:
   net::NetLogWithSource net_log_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockStreamSocket);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/net/network_change_notifier_factory_cast.h b/chromecast/net/network_change_notifier_factory_cast.h
index f9ef70f..55a2d54 100644
--- a/chromecast/net/network_change_notifier_factory_cast.h
+++ b/chromecast/net/network_change_notifier_factory_cast.h
@@ -15,13 +15,16 @@
     : public net::NetworkChangeNotifierFactory {
  public:
   NetworkChangeNotifierFactoryCast() {}
+
+  NetworkChangeNotifierFactoryCast(const NetworkChangeNotifierFactoryCast&) =
+      delete;
+  NetworkChangeNotifierFactoryCast& operator=(
+      const NetworkChangeNotifierFactoryCast&) = delete;
+
   ~NetworkChangeNotifierFactoryCast() override;
 
   // net::NetworkChangeNotifierFactory implementation:
   std::unique_ptr<net::NetworkChangeNotifier> CreateInstance() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierFactoryCast);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/net/network_change_notifier_factory_fuchsia.h b/chromecast/net/network_change_notifier_factory_fuchsia.h
index 0a97e24e..3b93f35 100644
--- a/chromecast/net/network_change_notifier_factory_fuchsia.h
+++ b/chromecast/net/network_change_notifier_factory_fuchsia.h
@@ -14,13 +14,16 @@
     : public net::NetworkChangeNotifierFactory {
  public:
   NetworkChangeNotifierFactoryFuchsia();
+
+  NetworkChangeNotifierFactoryFuchsia(
+      const NetworkChangeNotifierFactoryFuchsia&) = delete;
+  NetworkChangeNotifierFactoryFuchsia& operator=(
+      const NetworkChangeNotifierFactoryFuchsia&) = delete;
+
   ~NetworkChangeNotifierFactoryFuchsia() override;
 
   // net::NetworkChangeNotifierFactory implementation:
   std::unique_ptr<net::NetworkChangeNotifier> CreateInstance() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NetworkChangeNotifierFactoryFuchsia);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/renderer/activity_filtering_websocket_handshake_throttle.h b/chromecast/renderer/activity_filtering_websocket_handshake_throttle.h
index db17864..172da03 100644
--- a/chromecast/renderer/activity_filtering_websocket_handshake_throttle.h
+++ b/chromecast/renderer/activity_filtering_websocket_handshake_throttle.h
@@ -25,6 +25,12 @@
  public:
   explicit ActivityFilteringWebSocketHandshakeThrottle(
       ActivityUrlFilter* filter);
+
+  ActivityFilteringWebSocketHandshakeThrottle(
+      const ActivityFilteringWebSocketHandshakeThrottle&) = delete;
+  ActivityFilteringWebSocketHandshakeThrottle& operator=(
+      const ActivityFilteringWebSocketHandshakeThrottle&) = delete;
+
   ~ActivityFilteringWebSocketHandshakeThrottle() override;
 
   // blink::WebSocketHandshakeThrottle implementation:
@@ -34,8 +40,6 @@
 
  private:
   ActivityUrlFilter* const url_filter_;
-
-  DISALLOW_COPY_AND_ASSIGN(ActivityFilteringWebSocketHandshakeThrottle);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/renderer/cast_activity_url_filter_manager.h b/chromecast/renderer/cast_activity_url_filter_manager.h
index f242233c..4698b0c 100644
--- a/chromecast/renderer/cast_activity_url_filter_manager.h
+++ b/chromecast/renderer/cast_activity_url_filter_manager.h
@@ -25,6 +25,11 @@
 class CastActivityUrlFilterManager {
  public:
   CastActivityUrlFilterManager();
+
+  CastActivityUrlFilterManager(const CastActivityUrlFilterManager&) = delete;
+  CastActivityUrlFilterManager& operator=(const CastActivityUrlFilterManager&) =
+      delete;
+
   ~CastActivityUrlFilterManager();
 
   // Returns nullptr if no Activity URL filter exists for the render frame.
@@ -40,6 +45,10 @@
    public:
     explicit UrlFilterReceiver(content::RenderFrame* render_frame,
                                base::OnceCallback<void()> on_removed_callback);
+
+    UrlFilterReceiver(const UrlFilterReceiver&) = delete;
+    UrlFilterReceiver& operator=(const UrlFilterReceiver&) = delete;
+
     ~UrlFilterReceiver() override;
 
     // mojom::ActivityUrlFilterConfiguration implementation:
@@ -70,16 +79,12 @@
 
     base::WeakPtr<UrlFilterReceiver> weak_this_;
     base::WeakPtrFactory<UrlFilterReceiver> weak_factory_;
-
-    DISALLOW_COPY_AND_ASSIGN(UrlFilterReceiver);
   };
 
   base::flat_map<int, UrlFilterReceiver*> activity_url_filters_;
 
   base::WeakPtr<CastActivityUrlFilterManager> weak_this_;
   base::WeakPtrFactory<CastActivityUrlFilterManager> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastActivityUrlFilterManager);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/renderer/cast_content_renderer_client.h b/chromecast/renderer/cast_content_renderer_client.h
index b45dfbe..047cd4ba 100644
--- a/chromecast/renderer/cast_content_renderer_client.h
+++ b/chromecast/renderer/cast_content_renderer_client.h
@@ -54,6 +54,10 @@
   // link in an implementation as needed.
   static std::unique_ptr<CastContentRendererClient> Create();
 
+  CastContentRendererClient(const CastContentRendererClient&) = delete;
+  CastContentRendererClient& operator=(const CastContentRendererClient&) =
+      delete;
+
   ~CastContentRendererClient() override;
 
   // ContentRendererClient implementation:
@@ -145,8 +149,6 @@
   base::flat_map<int, scoped_refptr<IdentificationSettingsManager>>
       settings_managers_;
   std::unique_ptr<CastActivityUrlFilterManager> activity_url_filter_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastContentRendererClient);
 };
 
 }  // namespace shell
diff --git a/chromecast/renderer/cast_extensions_dispatcher_delegate.h b/chromecast/renderer/cast_extensions_dispatcher_delegate.h
index e10c6ea..c634add 100644
--- a/chromecast/renderer/cast_extensions_dispatcher_delegate.h
+++ b/chromecast/renderer/cast_extensions_dispatcher_delegate.h
@@ -12,6 +12,12 @@
     : public extensions::DispatcherDelegate {
  public:
   CastExtensionsDispatcherDelegate();
+
+  CastExtensionsDispatcherDelegate(const CastExtensionsDispatcherDelegate&) =
+      delete;
+  CastExtensionsDispatcherDelegate& operator=(
+      const CastExtensionsDispatcherDelegate&) = delete;
+
   ~CastExtensionsDispatcherDelegate() override;
 
  private:
@@ -28,8 +34,6 @@
   void InitializeBindingsSystem(
       extensions::Dispatcher* dispatcher,
       extensions::NativeExtensionBindingsSystem* bindings_system) override;
-
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionsDispatcherDelegate);
 };
 
 #endif  // CHROMECAST_RENDERER_CAST_EXTENSIONS_DISPATCHER_DELEGATE_H_
diff --git a/chromecast/renderer/cast_extensions_renderer_client.h b/chromecast/renderer/cast_extensions_renderer_client.h
index b40fcf5..6d3840a 100644
--- a/chromecast/renderer/cast_extensions_renderer_client.h
+++ b/chromecast/renderer/cast_extensions_renderer_client.h
@@ -16,6 +16,11 @@
 class CastExtensionsRendererClient : public ExtensionsRendererClient {
  public:
   CastExtensionsRendererClient();
+
+  CastExtensionsRendererClient(const CastExtensionsRendererClient&) = delete;
+  CastExtensionsRendererClient& operator=(const CastExtensionsRendererClient&) =
+      delete;
+
   ~CastExtensionsRendererClient() override;
 
   // ExtensionsRendererClient implementation.
@@ -28,8 +33,6 @@
 
  private:
   std::unique_ptr<Dispatcher> dispatcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastExtensionsRendererClient);
 };
 
 }  // namespace extensions
diff --git a/chromecast/renderer/extensions/extension_hooks_delegate.h b/chromecast/renderer/extensions/extension_hooks_delegate.h
index bb285ab..3a4c56d 100644
--- a/chromecast/renderer/extensions/extension_hooks_delegate.h
+++ b/chromecast/renderer/extensions/extension_hooks_delegate.h
@@ -21,6 +21,10 @@
  public:
   explicit ExtensionHooksDelegate(
       NativeRendererMessagingService* messaging_service);
+
+  ExtensionHooksDelegate(const ExtensionHooksDelegate&) = delete;
+  ExtensionHooksDelegate& operator=(const ExtensionHooksDelegate&) = delete;
+
   ~ExtensionHooksDelegate() override;
 
   // APIBindingHooksDelegate:
@@ -57,8 +61,6 @@
   // The messaging service to handle messaging calls.
   // Guaranteed to outlive this object.
   NativeRendererMessagingService* const messaging_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensionHooksDelegate);
 };
 
 }  // namespace extensions
diff --git a/chromecast/renderer/extensions/tabs_hooks_delegate.h b/chromecast/renderer/extensions/tabs_hooks_delegate.h
index 89a2423..4d01da8 100644
--- a/chromecast/renderer/extensions/tabs_hooks_delegate.h
+++ b/chromecast/renderer/extensions/tabs_hooks_delegate.h
@@ -20,6 +20,10 @@
 class TabsHooksDelegate : public APIBindingHooksDelegate {
  public:
   explicit TabsHooksDelegate(NativeRendererMessagingService* messaging_service);
+
+  TabsHooksDelegate(const TabsHooksDelegate&) = delete;
+  TabsHooksDelegate& operator=(const TabsHooksDelegate&) = delete;
+
   ~TabsHooksDelegate() override;
 
   // APIBindingHooksDelegate:
@@ -45,8 +49,6 @@
   // The messaging service to handle connect() and sendMessage() calls.
   // Guaranteed to outlive this object.
   NativeRendererMessagingService* const messaging_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(TabsHooksDelegate);
 };
 
 }  // namespace extensions
diff --git a/chromecast/renderer/js_channel_bindings.h b/chromecast/renderer/js_channel_bindings.h
index a65f875..9fe51d2 100644
--- a/chromecast/renderer/js_channel_bindings.h
+++ b/chromecast/renderer/js_channel_bindings.h
@@ -19,6 +19,10 @@
   explicit JsChannelBindings(
       content::RenderFrame* render_frame,
       mojo::PendingReceiver<mojom::JsChannelClient> receiver);
+
+  JsChannelBindings(const JsChannelBindings&) = delete;
+  JsChannelBindings& operator=(const JsChannelBindings&) = delete;
+
   ~JsChannelBindings() override;
 
  private:
@@ -41,8 +45,6 @@
   std::vector<std::pair<std::string, mojo::Remote<mojom::JsChannel>>> channels_;
 
   mojo::Receiver<mojom::JsChannelClient> receiver_;
-
-  DISALLOW_COPY_AND_ASSIGN(JsChannelBindings);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/renderer/media/media_caps_observer_impl.h b/chromecast/renderer/media/media_caps_observer_impl.h
index 02e2696..3fd3257 100644
--- a/chromecast/renderer/media/media_caps_observer_impl.h
+++ b/chromecast/renderer/media/media_caps_observer_impl.h
@@ -19,6 +19,10 @@
  public:
   MediaCapsObserverImpl(mojo::PendingRemote<mojom::MediaCapsObserver>* proxy,
                         SupportedCodecProfileLevelsMemo* supported_profiles);
+
+  MediaCapsObserverImpl(const MediaCapsObserverImpl&) = delete;
+  MediaCapsObserverImpl& operator=(const MediaCapsObserverImpl&) = delete;
+
   ~MediaCapsObserverImpl() override;
 
  private:
@@ -35,8 +39,6 @@
 
   SupportedCodecProfileLevelsMemo* supported_profiles_;
   mojo::Receiver<mojom::MediaCapsObserver> receiver_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaCapsObserverImpl);
 };
 
 }  // namespace media
diff --git a/chromecast/renderer/memory_pressure_observer_impl.h b/chromecast/renderer/memory_pressure_observer_impl.h
index ac6398f..fb602c53 100644
--- a/chromecast/renderer/memory_pressure_observer_impl.h
+++ b/chromecast/renderer/memory_pressure_observer_impl.h
@@ -16,14 +16,17 @@
  public:
   MemoryPressureObserverImpl(
       mojo::PendingRemote<mojom::MemoryPressureObserver>* observer);
+
+  MemoryPressureObserverImpl(const MemoryPressureObserverImpl&) = delete;
+  MemoryPressureObserverImpl& operator=(const MemoryPressureObserverImpl&) =
+      delete;
+
   ~MemoryPressureObserverImpl() override;
 
  private:
   void MemoryPressureLevelChanged(int32_t pressure_level) override;
 
   mojo::Receiver<mojom::MemoryPressureObserver> receiver_;
-
-  DISALLOW_COPY_AND_ASSIGN(MemoryPressureObserverImpl);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/renderer/queryable_data_store.h b/chromecast/renderer/queryable_data_store.h
index 579e35a..e52622b 100644
--- a/chromecast/renderer/queryable_data_store.h
+++ b/chromecast/renderer/queryable_data_store.h
@@ -26,6 +26,10 @@
  public:
   explicit QueryableDataStore(
       const scoped_refptr<base::TaskRunner> render_main_thread);
+
+  QueryableDataStore(const QueryableDataStore&) = delete;
+  QueryableDataStore& operator=(const QueryableDataStore&) = delete;
+
   ~QueryableDataStore() override;
 
   void BindQueryableDataStoreReceiver(
@@ -38,8 +42,6 @@
   const scoped_refptr<base::TaskRunner> render_main_thread_;
 
   mojo::ReceiverSet<shell::mojom::QueryableDataStore> queryable_data_receivers_;
-
-  DISALLOW_COPY_AND_ASSIGN(QueryableDataStore);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/service/cast_service.h b/chromecast/service/cast_service.h
index 74795fd..6a94549 100644
--- a/chromecast/service/cast_service.h
+++ b/chromecast/service/cast_service.h
@@ -18,6 +18,9 @@
 
 class CastService {
  public:
+  CastService(const CastService&) = delete;
+  CastService& operator=(const CastService&) = delete;
+
   virtual ~CastService();
 
   // Initializes/finalizes the cast service.
@@ -56,8 +59,6 @@
  private:
   bool stopped_;
   const std::unique_ptr<base::ThreadChecker> thread_checker_;
-
-  DISALLOW_COPY_AND_ASSIGN(CastService);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/tracing/system_tracer.h b/chromecast/tracing/system_tracer.h
index b2b271d..4e880b7 100644
--- a/chromecast/tracing/system_tracer.h
+++ b/chromecast/tracing/system_tracer.h
@@ -20,6 +20,9 @@
  public:
   static std::unique_ptr<SystemTracer> Create();
 
+  SystemTracer(const SystemTracer&) = delete;
+  SystemTracer& operator=(const SystemTracer&) = delete;
+
   virtual ~SystemTracer() = default;
 
   enum class Status {
@@ -45,9 +48,6 @@
 
  protected:
   SystemTracer() = default;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(SystemTracer);
 };
 
 }  // namespace chromecast
diff --git a/chromecast/ui/media_control_ui.h b/chromecast/ui/media_control_ui.h
index b8b5399..345662c 100644
--- a/chromecast/ui/media_control_ui.h
+++ b/chromecast/ui/media_control_ui.h
@@ -29,6 +29,10 @@
 class MediaControlUi : public mojom::MediaControlUi {
  public:
   explicit MediaControlUi(CastWindowManager* window_manager);
+
+  MediaControlUi(const MediaControlUi&) = delete;
+  MediaControlUi& operator=(const MediaControlUi&) = delete;
+
   ~MediaControlUi() override;
 
   void SetBounds(const gfx::Rect& new_bounds);
@@ -96,8 +100,6 @@
 
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<MediaControlUi> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaControlUi);
 };
 
 }  // namespace chromecast
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 54ac1ae..fc88c23 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-14236.0.0
\ No newline at end of file
+14237.0.0
\ No newline at end of file
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd
index 5f32b7b..a248ebe 100644
--- a/chromeos/chromeos_strings.grd
+++ b/chromeos/chromeos_strings.grd
@@ -1010,9 +1010,6 @@
       <message name="IDS_DIAGNOSTICS_EID_LABEL" desc="The label for a Cellular network's EID.">
         EID
       </message>
-      <message name="IDS_DIAGNOSTICS_FAILED_TEST_TEXT" desc="The text that displays the test that failed.">
-        <ph name="TEST_NAME">$1<ex>Stress</ex></ph> test failed
-      </message>
       <message name="IDS_DIAGNOSTICS_LOCAL_NETWORK_GROUP_LABEL" desc="The label for the group of tests related to the device's local network.">
         Local Network
       </message>
@@ -1022,6 +1019,48 @@
       <message name="IDS_DIAGNOSTICS_INTERNET_CONNECTIVITY_GROUP_LABEL" desc="The label for the group of tests related to internet connectivity.">
         Internet Connectivity
       </message>
+      <message name="IDS_DIAGNOSTICS_LAN_CONNECTIVITY_FAILED_TEXT" desc="The text that displays when the `Lan Connectivity` test fails." translateable="false">
+        Unable to contact gateway
+      </message>
+      <message name="IDS_DIAGNOSTICS_GATEWAY_CAN_BE_PINGED_FAILED_TEXT" desc="The text that displays when the `Gateway can be pinged` test fails." translateable="false">
+        Unable to contact gateway
+      </message>
+      <message name="IDS_DIAGNOSTICS_DNS_RESOLVER_PRESENT_FAILED_TEXT" desc="The text that displays when the `DNS resolver present` test fails." translateable="false">
+        No DNS servers are configured
+      </message>
+      <message name="IDS_DIAGNOSTICS_DNS_RESOLUTION_FAILED_TEXT" desc="The text that displays when the `DNS resolution` test fails." translateable="false">
+        Unable to resolve DNS
+      </message>
+      <message name="IDS_DIAGNOSTICS_DNS_LATENCY_FAILED_TEXT" desc="The text that displays when the `DNS latency` test fails." translateable="false">
+        DNS resolution has high latency
+      </message>
+      <message name="IDS_DIAGNOSTICS_SIGNAL_STRENGTH_FAILED_TEXT" desc="The text that displays when the `Signal strength` test fails." translateable="false">
+        Low signal strength, try to move closer to the access point
+      </message>
+      <message name="IDS_DIAGNOSTICS_CAPTIVE_PORTAL_FAILED_TEXT" desc="The text that displays when the `Captive portal` test fails." translateable="false">
+        This network may have a captive portal
+      </message>
+      <message name="IDS_DIAGNOSTICS_HAS_SECURE_WIFI_CONNECTION_FAILED_TEXT" desc="The text that displays when the `Has secure Wi-Fi connection` test fails." translateable="false">
+        You are using an open network
+      </message>
+      <message name="IDS_DIAGNOSTICS_HTTPS_FIREWALL_FAILED_TEXT" desc="The text that displays when the `HTTPS firewall` test fails." translateable="false">
+        Unable to connect through firewall to HTTPS (port 443) websites
+      </message>
+      <message name="IDS_DIAGNOSTICS_HTTP_FIREWALL_FAILED_TEXT" desc="The text that displays when the `HTTP firewall` test fails." translateable="false">
+        Unable to connect through firewall to HTTP (port 80) websites
+      </message>
+      <message name="IDS_DIAGNOSTICS_HTTPS_LATENCY_FAILED_TEXT" desc="The text that displays when the `HTTPS latency` test fails." translateable="false">
+        High latency to HTTPS (port 443) websites
+      </message>
+      <message name="IDS_DIAGNOSTICS_ARC_PING_FAILED_TEXT" desc="The text that displays when the `ARC ping` test fails." translateable="false">
+        Unable to contact the gateway from Android
+      </message>
+      <message name="IDS_DIAGNOSTICS_ARC_HTTP_FAILED_TEXT" desc="The text that displays when the `ARC HTTP` test fails." translateable="false">
+        Unable to connect through firewall to HTTP (port 80) websites from Android
+      </message>
+      <message name="IDS_DIAGNOSTICS_ARC_DNS_RESOLUTION_FAILED_TEXT" desc="The text that displays when the `ARC DNS resolution` test fails." translateable="false">
+        Unable to resolve DNS from Android
+      </message>
 
       <!-- Input diagnostics -->
       <message name="IDS_INPUT_DIAGNOSTICS_RUN_TEST" desc="Text for the button that runs a test for a specific input device">
diff --git a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_FAILED_TEST_TEXT.png.sha1 b/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_FAILED_TEST_TEXT.png.sha1
deleted file mode 100644
index 54d4175..0000000
--- a/chromeos/chromeos_strings_grd/IDS_DIAGNOSTICS_FAILED_TEST_TEXT.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-584cb9d47a2d01dd7f4f46ffe863742f8e420109
\ No newline at end of file
diff --git a/chromeos/components/phonehub/BUILD.gn b/chromeos/components/phonehub/BUILD.gn
index 9909e608..123ac94f 100644
--- a/chromeos/components/phonehub/BUILD.gn
+++ b/chromeos/components/phonehub/BUILD.gn
@@ -19,6 +19,8 @@
     "camera_roll_item.h",
     "camera_roll_manager.cc",
     "camera_roll_manager.h",
+    "camera_roll_manager_impl.cc",
+    "camera_roll_manager_impl.h",
     "camera_roll_thumbnail_decoder.h",
     "camera_roll_thumbnail_decoder_impl.cc",
     "camera_roll_thumbnail_decoder_impl.h",
@@ -138,6 +140,8 @@
   sources = [
     "fake_browser_tabs_model_provider.cc",
     "fake_browser_tabs_model_provider.h",
+    "fake_camera_roll_manager.cc",
+    "fake_camera_roll_manager.h",
     "fake_connection_scheduler.cc",
     "fake_connection_scheduler.h",
     "fake_do_not_disturb_controller.cc",
@@ -206,7 +210,7 @@
   sources = [
     "browser_tabs_model_controller_unittest.cc",
     "browser_tabs_model_unittest.cc",
-    "camera_roll_manager_unittest.cc",
+    "camera_roll_manager_impl_unittest.cc",
     "camera_roll_thumbnail_decoder_impl_unittest.cc",
     "connection_scheduler_impl_unittest.cc",
     "cros_state_sender_unittest.cc",
diff --git a/chromeos/components/phonehub/camera_roll_item.cc b/chromeos/components/phonehub/camera_roll_item.cc
index a1d20b9..ac4cd965 100644
--- a/chromeos/components/phonehub/camera_roll_item.cc
+++ b/chromeos/components/phonehub/camera_roll_item.cc
@@ -20,5 +20,18 @@
 
 CameraRollItem::~CameraRollItem() = default;
 
+bool CameraRollItem::operator==(const CameraRollItem& other) const {
+  return metadata_.key() == other.metadata().key() &&
+         metadata_.mime_type() == other.metadata().mime_type() &&
+         metadata_.last_modified_millis() ==
+             other.metadata().last_modified_millis() &&
+         metadata_.file_size_bytes() == other.metadata().file_size_bytes() &&
+         metadata_.file_name() == other.metadata().file_name();
+}
+
+bool CameraRollItem::operator!=(const CameraRollItem& other) const {
+  return !operator==(other);
+}
+
 }  // namespace phonehub
 }  // namespace chromeos
diff --git a/chromeos/components/phonehub/camera_roll_item.h b/chromeos/components/phonehub/camera_roll_item.h
index 4a201e1b..618bfa8 100644
--- a/chromeos/components/phonehub/camera_roll_item.h
+++ b/chromeos/components/phonehub/camera_roll_item.h
@@ -21,6 +21,10 @@
   CameraRollItem& operator=(const CameraRollItem&);
   virtual ~CameraRollItem();
 
+  // True iff both both items have the same metadata values.
+  bool operator==(const CameraRollItem& other) const;
+  bool operator!=(const CameraRollItem& other) const;
+
   // Returns the metadata of this item.
   const proto::CameraRollItemMetadata& metadata() const { return metadata_; }
   // Returns the decoded thumbnail of this item.
diff --git a/chromeos/components/phonehub/camera_roll_manager.cc b/chromeos/components/phonehub/camera_roll_manager.cc
index b96920707..24a6788 100644
--- a/chromeos/components/phonehub/camera_roll_manager.cc
+++ b/chromeos/components/phonehub/camera_roll_manager.cc
@@ -4,123 +4,15 @@
 
 #include "chromeos/components/phonehub/camera_roll_manager.h"
 
-#include "base/bind.h"
-#include "base/memory/weak_ptr.h"
-#include "base/observer_list.h"
+#include "chromeos/components/multidevice/logging/logging.h"
 #include "chromeos/components/phonehub/camera_roll_item.h"
-#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h"
-#include "chromeos/components/phonehub/message_receiver.h"
-#include "chromeos/components/phonehub/message_sender.h"
-#include "chromeos/components/phonehub/proto/phonehub_api.pb.h"
 
 namespace chromeos {
 namespace phonehub {
-namespace {
 
-bool IsCameraRollSupportedOnAndroidDevice(
-    const proto::CameraRollAccessState& access_state) {
-  return access_state.feature_enabled() &&
-         access_state.storage_permission_granted();
-}
+CameraRollManager::CameraRollManager() = default;
 
-}  // namespace
-
-CameraRollManager::CameraRollManager(
-    MessageReceiver* message_receiver,
-    MessageSender* message_sender,
-    multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client)
-    : message_receiver_(message_receiver),
-      message_sender_(message_sender),
-      multidevice_setup_client_(multidevice_setup_client),
-      thumbnail_decoder_(std::make_unique<CameraRollThumbnailDecoderImpl>()) {
-  max_item_count_ = 4;  // TODO(mattwalliser): Pull this value from config.
-  message_receiver->AddObserver(this);
-  multidevice_setup_client_->AddObserver(this);
-}
-
-CameraRollManager::~CameraRollManager() {
-  message_receiver_->RemoveObserver(this);
-  multidevice_setup_client_->RemoveObserver(this);
-}
-
-void CameraRollManager::OnPhoneStatusSnapshotReceived(
-    proto::PhoneStatusSnapshot phone_status_snapshot) {
-  if (!IsCameraRollSupportedOnAndroidDevice(
-          phone_status_snapshot.properties().camera_roll_access_state()) ||
-      !IsCameraRollSettingEnabled()) {
-    ClearCurrentItems();
-    CancelPendingThumbnailRequests();
-    return;
-  }
-
-  SendFetchCameraRollItemsRequest();
-}
-
-void CameraRollManager::OnPhoneStatusUpdateReceived(
-    proto::PhoneStatusUpdate phone_status_update) {
-  if (!IsCameraRollSupportedOnAndroidDevice(
-          phone_status_update.properties().camera_roll_access_state()) ||
-      !IsCameraRollSettingEnabled()) {
-    ClearCurrentItems();
-    CancelPendingThumbnailRequests();
-    return;
-  }
-
-  if (phone_status_update.has_camera_roll_updates()) {
-    SendFetchCameraRollItemsRequest();
-  }
-}
-
-void CameraRollManager::SendFetchCameraRollItemsRequest() {
-  // Clears pending thumbnail decode requests to avoid changing the current item
-  // set after sending it with the |FetchCameraRollItemsRequest|. These pending
-  // thumbnails will be invalidated anyway when the new response is received.
-  CancelPendingThumbnailRequests();
-
-  proto::FetchCameraRollItemsRequest request;
-  request.set_max_item_count(max_item_count_);
-  for (const CameraRollItem& current_item : current_items_) {
-    *request.add_current_item_metadata() = current_item.metadata();
-  }
-  message_sender_->SendFetchCameraRollItemsRequest(request);
-}
-
-void CameraRollManager::ClearCurrentItems() {
-  if (current_items_.empty()) {
-    return;
-  }
-
-  current_items_.clear();
-  for (auto& observer : observer_list_) {
-    observer.OnCameraRollItemsChanged();
-  }
-}
-
-void CameraRollManager::OnFetchCameraRollItemsResponseReceived(
-    const proto::FetchCameraRollItemsResponse& response) {
-  thumbnail_decoder_->BatchDecode(
-      response, current_items(),
-      base::BindOnce(&CameraRollManager::OnItemThumbnailsDecoded,
-                     weak_ptr_factory_.GetWeakPtr()));
-}
-
-void CameraRollManager::OnItemThumbnailsDecoded(
-    CameraRollThumbnailDecoder::BatchDecodeResult result,
-    const std::vector<CameraRollItem>& items) {
-  if (result == CameraRollThumbnailDecoder::BatchDecodeResult::kSuccess) {
-    current_items_ = items;
-    // The phone only sends FetchCameraRollItemsResponse when the set of items
-    // has changed. Always alert the observers in this case.
-    for (auto& observer : observer_list_) {
-      observer.OnCameraRollItemsChanged();
-    }
-  }
-  // TODO(http://crbug.com/1221297): log and handle failed decode requests.
-}
-
-void CameraRollManager::CancelPendingThumbnailRequests() {
-  weak_ptr_factory_.InvalidateWeakPtrs();
-}
+CameraRollManager::~CameraRollManager() = default;
 
 void CameraRollManager::AddObserver(Observer* observer) {
   observer_list_.AddObserver(observer);
@@ -130,20 +22,27 @@
   observer_list_.RemoveObserver(observer);
 }
 
-bool CameraRollManager::IsCameraRollSettingEnabled() {
-  multidevice_setup::mojom::FeatureState camera_roll_feature_state =
-      multidevice_setup_client_->GetFeatureState(
-          multidevice_setup::mojom::Feature::kPhoneHubCameraRoll);
-  return camera_roll_feature_state ==
-         multidevice_setup::mojom::FeatureState::kEnabledByUser;
+void CameraRollManager::SetCurrentItems(
+    const std::vector<CameraRollItem>& items) {
+  if (current_items_ == items) {
+    return;
+  }
+  current_items_ = items;
+  NotifyCameraRollItemsChanged();
 }
 
-void CameraRollManager::OnFeatureStatesChanged(
-    const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
-        feature_states_map) {
-  if (!IsCameraRollSettingEnabled()) {
-    ClearCurrentItems();
-    CancelPendingThumbnailRequests();
+void CameraRollManager::ClearCurrentItems() {
+  if (current_items_.empty()) {
+    return;
+  }
+  current_items_.clear();
+  NotifyCameraRollItemsChanged();
+}
+
+void CameraRollManager::NotifyCameraRollItemsChanged() {
+  PA_LOG(INFO) << "Updated the list of Camera Roll items";
+  for (auto& observer : observer_list_) {
+    observer.OnCameraRollItemsChanged();
   }
 }
 
diff --git a/chromeos/components/phonehub/camera_roll_manager.h b/chromeos/components/phonehub/camera_roll_manager.h
index a1abda1..5dea0671 100644
--- a/chromeos/components/phonehub/camera_roll_manager.h
+++ b/chromeos/components/phonehub/camera_roll_manager.h
@@ -5,42 +5,29 @@
 #ifndef CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_MANAGER_H_
 #define CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_MANAGER_H_
 
-#include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
-#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder.h"
-#include "chromeos/components/phonehub/message_receiver.h"
-#include "chromeos/components/phonehub/proto/phonehub_api.pb.h"
-#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
-#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
 
 namespace chromeos {
 namespace phonehub {
 
 class CameraRollItem;
-class MessageSender;
 
 // Manages camera roll items sent from the connected Android device.
-class CameraRollManager
-    : public MessageReceiver::Observer,
-      public multidevice_setup::MultiDeviceSetupClient::Observer {
+class CameraRollManager {
  public:
   class Observer : public base::CheckedObserver {
    public:
     ~Observer() override = default;
 
     // Notifies observers that the set of current camera roll items has changed.
-    // The item set can be retrieved from CameraRollManager::GetCurrentItems().
+    // The item set can be retrieved from CameraRollManager::current_items().
     virtual void OnCameraRollItemsChanged() = 0;
   };
 
-  CameraRollManager(
-      MessageReceiver* message_receiver,
-      MessageSender* message_sender,
-      multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client);
   CameraRollManager(const CameraRollManager&) = delete;
   CameraRollManager& operator=(const CameraRollManager&) = delete;
-  ~CameraRollManager() override;
+  virtual ~CameraRollManager();
 
   // Returns the set of current camera roll items in the order in which they
   // should be displayed
@@ -51,42 +38,17 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
- private:
-  friend class CameraRollManagerTest;
+ protected:
+  CameraRollManager();
 
-  // MessageReceiver::Observer
-  void OnPhoneStatusSnapshotReceived(
-      proto::PhoneStatusSnapshot phone_status_snapshot) override;
-  void OnPhoneStatusUpdateReceived(
-      proto::PhoneStatusUpdate phone_status_update) override;
-  void OnFetchCameraRollItemsResponseReceived(
-      const proto::FetchCameraRollItemsResponse& response) override;
-
-  // MultiDeviceSetupClient::Observer:
-  void OnFeatureStatesChanged(
-      const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
-          feature_states_map) override;
-
-  void SendFetchCameraRollItemsRequest();
+  void SetCurrentItems(const std::vector<CameraRollItem>& items);
   void ClearCurrentItems();
-  void OnItemThumbnailsDecoded(
-      CameraRollThumbnailDecoder::BatchDecodeResult result,
-      const std::vector<CameraRollItem>& items);
-  void CancelPendingThumbnailRequests();
-  bool IsCameraRollSettingEnabled();
 
-  MessageReceiver* message_receiver_;
-  MessageSender* message_sender_;
-  multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_;
+  void NotifyCameraRollItemsChanged();
 
-  int32_t max_item_count_;
+ private:
   std::vector<CameraRollItem> current_items_;
-
   base::ObserverList<Observer> observer_list_;
-
-  std::unique_ptr<CameraRollThumbnailDecoder> thumbnail_decoder_;
-  // Contains pending callbacks passed to the |CameraRollThumbnailDecoder|.
-  base::WeakPtrFactory<CameraRollManager> weak_ptr_factory_{this};
 };
 
 }  // namespace phonehub
diff --git a/chromeos/components/phonehub/camera_roll_manager_impl.cc b/chromeos/components/phonehub/camera_roll_manager_impl.cc
new file mode 100644
index 0000000..2e8b510
--- /dev/null
+++ b/chromeos/components/phonehub/camera_roll_manager_impl.cc
@@ -0,0 +1,128 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/components/phonehub/camera_roll_manager_impl.h"
+
+#include "base/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "chromeos/components/phonehub/camera_roll_item.h"
+#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder_impl.h"
+#include "chromeos/components/phonehub/message_receiver.h"
+#include "chromeos/components/phonehub/message_sender.h"
+#include "chromeos/components/phonehub/proto/phonehub_api.pb.h"
+
+namespace chromeos {
+namespace phonehub {
+namespace {
+
+bool IsCameraRollSupportedOnAndroidDevice(
+    const proto::CameraRollAccessState& access_state) {
+  return access_state.feature_enabled() &&
+         access_state.storage_permission_granted();
+}
+
+constexpr int kMaxCameraRollItemCount = 4;
+
+}  // namespace
+
+CameraRollManagerImpl::CameraRollManagerImpl(
+    MessageReceiver* message_receiver,
+    MessageSender* message_sender,
+    multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client)
+    : message_receiver_(message_receiver),
+      message_sender_(message_sender),
+      multidevice_setup_client_(multidevice_setup_client),
+      thumbnail_decoder_(std::make_unique<CameraRollThumbnailDecoderImpl>()) {
+  message_receiver->AddObserver(this);
+  multidevice_setup_client_->AddObserver(this);
+}
+
+CameraRollManagerImpl::~CameraRollManagerImpl() {
+  message_receiver_->RemoveObserver(this);
+  multidevice_setup_client_->RemoveObserver(this);
+}
+
+void CameraRollManagerImpl::OnPhoneStatusSnapshotReceived(
+    proto::PhoneStatusSnapshot phone_status_snapshot) {
+  if (!IsCameraRollSupportedOnAndroidDevice(
+          phone_status_snapshot.properties().camera_roll_access_state()) ||
+      !IsCameraRollSettingEnabled()) {
+    ClearCurrentItems();
+    CancelPendingThumbnailRequests();
+    return;
+  }
+
+  SendFetchCameraRollItemsRequest();
+}
+
+void CameraRollManagerImpl::OnPhoneStatusUpdateReceived(
+    proto::PhoneStatusUpdate phone_status_update) {
+  if (!IsCameraRollSupportedOnAndroidDevice(
+          phone_status_update.properties().camera_roll_access_state()) ||
+      !IsCameraRollSettingEnabled()) {
+    ClearCurrentItems();
+    CancelPendingThumbnailRequests();
+    return;
+  }
+
+  if (phone_status_update.has_camera_roll_updates()) {
+    SendFetchCameraRollItemsRequest();
+  }
+}
+
+void CameraRollManagerImpl::OnFetchCameraRollItemsResponseReceived(
+    const proto::FetchCameraRollItemsResponse& response) {
+  thumbnail_decoder_->BatchDecode(
+      response, current_items(),
+      base::BindOnce(&CameraRollManagerImpl::OnItemThumbnailsDecoded,
+                     weak_ptr_factory_.GetWeakPtr()));
+}
+
+void CameraRollManagerImpl::SendFetchCameraRollItemsRequest() {
+  // Clears pending thumbnail decode requests to avoid changing the current item
+  // set after sending it with the |FetchCameraRollItemsRequest|. These pending
+  // thumbnails will be invalidated anyway when the new response is received.
+  CancelPendingThumbnailRequests();
+
+  proto::FetchCameraRollItemsRequest request;
+  request.set_max_item_count(kMaxCameraRollItemCount);
+  for (const CameraRollItem& current_item : current_items()) {
+    *request.add_current_item_metadata() = current_item.metadata();
+  }
+  message_sender_->SendFetchCameraRollItemsRequest(request);
+}
+
+void CameraRollManagerImpl::OnItemThumbnailsDecoded(
+    CameraRollThumbnailDecoder::BatchDecodeResult result,
+    const std::vector<CameraRollItem>& items) {
+  if (result == CameraRollThumbnailDecoder::BatchDecodeResult::kSuccess) {
+    SetCurrentItems(items);
+  }
+  // TODO(http://crbug.com/1221297): log and handle failed decode requests.
+}
+
+void CameraRollManagerImpl::CancelPendingThumbnailRequests() {
+  weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
+bool CameraRollManagerImpl::IsCameraRollSettingEnabled() {
+  multidevice_setup::mojom::FeatureState camera_roll_feature_state =
+      multidevice_setup_client_->GetFeatureState(
+          multidevice_setup::mojom::Feature::kPhoneHubCameraRoll);
+  return camera_roll_feature_state ==
+         multidevice_setup::mojom::FeatureState::kEnabledByUser;
+}
+
+void CameraRollManagerImpl::OnFeatureStatesChanged(
+    const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
+        feature_states_map) {
+  if (!IsCameraRollSettingEnabled()) {
+    ClearCurrentItems();
+    CancelPendingThumbnailRequests();
+  }
+}
+
+}  // namespace phonehub
+}  // namespace chromeos
diff --git a/chromeos/components/phonehub/camera_roll_manager_impl.h b/chromeos/components/phonehub/camera_roll_manager_impl.h
new file mode 100644
index 0000000..08cdefb
--- /dev/null
+++ b/chromeos/components/phonehub/camera_roll_manager_impl.h
@@ -0,0 +1,70 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_MANAGER_IMPL_H_
+#define CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_MANAGER_IMPL_H_
+
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
+#include "chromeos/components/phonehub/camera_roll_manager.h"
+#include "chromeos/components/phonehub/camera_roll_thumbnail_decoder.h"
+#include "chromeos/components/phonehub/message_receiver.h"
+#include "chromeos/components/phonehub/proto/phonehub_api.pb.h"
+#include "chromeos/services/multidevice_setup/public/cpp/multidevice_setup_client.h"
+#include "chromeos/services/multidevice_setup/public/mojom/multidevice_setup.mojom.h"
+
+namespace chromeos {
+namespace phonehub {
+
+class CameraRollItem;
+class MessageSender;
+
+// Manages camera roll items sent from the connected Android device.
+class CameraRollManagerImpl
+    : public CameraRollManager,
+      public MessageReceiver::Observer,
+      public multidevice_setup::MultiDeviceSetupClient::Observer {
+ public:
+  CameraRollManagerImpl(
+      MessageReceiver* message_receiver,
+      MessageSender* message_sender,
+      multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client);
+  ~CameraRollManagerImpl() override;
+
+ private:
+  friend class CameraRollManagerImplTest;
+
+  // MessageReceiver::Observer
+  void OnPhoneStatusSnapshotReceived(
+      proto::PhoneStatusSnapshot phone_status_snapshot) override;
+  void OnPhoneStatusUpdateReceived(
+      proto::PhoneStatusUpdate phone_status_update) override;
+  void OnFetchCameraRollItemsResponseReceived(
+      const proto::FetchCameraRollItemsResponse& response) override;
+
+  // MultiDeviceSetupClient::Observer:
+  void OnFeatureStatesChanged(
+      const multidevice_setup::MultiDeviceSetupClient::FeatureStatesMap&
+          feature_states_map) override;
+
+  void SendFetchCameraRollItemsRequest();
+  void OnItemThumbnailsDecoded(
+      CameraRollThumbnailDecoder::BatchDecodeResult result,
+      const std::vector<CameraRollItem>& items);
+  void CancelPendingThumbnailRequests();
+  bool IsCameraRollSettingEnabled();
+
+  MessageReceiver* message_receiver_;
+  MessageSender* message_sender_;
+  multidevice_setup::MultiDeviceSetupClient* multidevice_setup_client_;
+
+  std::unique_ptr<CameraRollThumbnailDecoder> thumbnail_decoder_;
+  base::WeakPtrFactory<CameraRollManagerImpl> weak_ptr_factory_{this};
+};
+
+}  // namespace phonehub
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_PHONEHUB_CAMERA_ROLL_MANAGER_IMPL_H_
diff --git a/chromeos/components/phonehub/camera_roll_manager_unittest.cc b/chromeos/components/phonehub/camera_roll_manager_impl_unittest.cc
similarity index 93%
rename from chromeos/components/phonehub/camera_roll_manager_unittest.cc
rename to chromeos/components/phonehub/camera_roll_manager_impl_unittest.cc
index ee356f79..9f67f6e 100644
--- a/chromeos/components/phonehub/camera_roll_manager_unittest.cc
+++ b/chromeos/components/phonehub/camera_roll_manager_impl_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 "chromeos/components/phonehub/camera_roll_manager.h"
+#include "chromeos/components/phonehub/camera_roll_manager_impl.h"
 
 #include "base/callback.h"
 #include "base/strings/utf_string_conversions.h"
@@ -104,18 +104,19 @@
   BatchDecodeCallback pending_callback_;
 };
 
-class CameraRollManagerTest : public testing::Test {
+class CameraRollManagerImplTest : public testing::Test {
  protected:
-  CameraRollManagerTest() = default;
-  CameraRollManagerTest(const CameraRollManagerTest&) = delete;
-  CameraRollManagerTest& operator=(const CameraRollManagerTest&) = delete;
-  ~CameraRollManagerTest() override = default;
+  CameraRollManagerImplTest() = default;
+  CameraRollManagerImplTest(const CameraRollManagerImplTest&) = delete;
+  CameraRollManagerImplTest& operator=(const CameraRollManagerImplTest&) =
+      delete;
+  ~CameraRollManagerImplTest() override = default;
 
   void SetUp() override {
     fake_multidevice_setup_client_ =
         std::make_unique<multidevice_setup::FakeMultiDeviceSetupClient>();
     SetCameraRollFeatureSettings(true);
-    camera_roll_manager_ = std::make_unique<CameraRollManager>(
+    camera_roll_manager_ = std::make_unique<CameraRollManagerImpl>(
         &fake_message_receiver_, &fake_message_sender_,
         fake_multidevice_setup_client_.get());
     camera_roll_manager_->thumbnail_decoder_ =
@@ -183,11 +184,11 @@
 
  private:
   FakeMessageSender fake_message_sender_;
-  std::unique_ptr<CameraRollManager> camera_roll_manager_;
+  std::unique_ptr<CameraRollManagerImpl> camera_roll_manager_;
   FakeObserver fake_observer_;
 };
 
-TEST_F(CameraRollManagerTest, OnCameraRollItemsReceived) {
+TEST_F(CameraRollManagerImplTest, OnCameraRollItemsReceived) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key3");
   PopulateItemProto(response.add_items(), "key2");
@@ -200,7 +201,7 @@
   VerifyCurrentItemsMatchResponse(response);
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnCameraRollItemsReceivedWithThumbnailDecodingError) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key3");
@@ -214,7 +215,7 @@
   EXPECT_EQ(0, GetCurrentItemsCount());
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnCameraRollItemsReceivedWithPendingThumbnailDecodedRequest) {
   proto::FetchCameraRollItemsResponse first_response;
   PopulateItemProto(first_response.add_items(), "key2");
@@ -235,7 +236,7 @@
   VerifyCurrentItemsMatchResponse(second_response);
 }
 
-TEST_F(CameraRollManagerTest, OnCameraRollItemsReceivedWithExistingItems) {
+TEST_F(CameraRollManagerImplTest, OnCameraRollItemsReceivedWithExistingItems) {
   proto::FetchCameraRollItemsResponse first_response;
   PopulateItemProto(first_response.add_items(), "key3");
   PopulateItemProto(first_response.add_items(), "key2");
@@ -262,7 +263,7 @@
   VerifyCurrentItemsMatchResponse(second_response);
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnPhoneStatusUpdateReceivedWithoutCameraRollUpdates) {
   proto::PhoneStatusUpdate update;
   update.set_has_camera_roll_updates(false);
@@ -276,7 +277,7 @@
   EXPECT_EQ(0, GetOnCameraRollItemChangedCallCount());
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnPhoneStatusUpdateReceivedWithCameraRollUpdates) {
   proto::PhoneStatusUpdate update;
   update.set_has_camera_roll_updates(true);
@@ -292,7 +293,8 @@
   EXPECT_EQ(0, GetOnCameraRollItemChangedCallCount());
 }
 
-TEST_F(CameraRollManagerTest, OnPhoneStatusUpdateReceivedWithExistingItems) {
+TEST_F(CameraRollManagerImplTest,
+       OnPhoneStatusUpdateReceivedWithExistingItems) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key3");
   PopulateItemProto(response.add_items(), "key2");
@@ -323,7 +325,8 @@
       GetSentFetchCameraRollItemsRequest().current_item_metadata(2));
 }
 
-TEST_F(CameraRollManagerTest, OnPhoneStatusUpdateReceivedWithFeatureDisabled) {
+TEST_F(CameraRollManagerImplTest,
+       OnPhoneStatusUpdateReceivedWithFeatureDisabled) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key2");
   PopulateItemProto(response.add_items(), "key1");
@@ -342,7 +345,7 @@
   EXPECT_EQ(0, GetCurrentItemsCount());
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnPhoneStatusUpdateReceivedWithCameraRollSettingsDisabled) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key2");
@@ -364,7 +367,7 @@
   EXPECT_EQ(0, GetCurrentItemsCount());
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnPhoneStatusUpdateReceivedWithoutStoragePermission) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key2");
@@ -384,7 +387,7 @@
   EXPECT_EQ(0, GetCurrentItemsCount());
 }
 
-TEST_F(CameraRollManagerTest, OnPhoneStatusSnapshotReceived) {
+TEST_F(CameraRollManagerImplTest, OnPhoneStatusSnapshotReceived) {
   proto::PhoneStatusSnapshot snapshot;
   proto::CameraRollAccessState* access_state =
       snapshot.mutable_properties()->mutable_camera_roll_access_state();
@@ -396,7 +399,7 @@
   EXPECT_EQ(0, GetOnCameraRollItemChangedCallCount());
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnPhoneStatusSnapshotReceivedWithFeatureDisabled) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key2");
@@ -416,7 +419,7 @@
   EXPECT_EQ(0, GetCurrentItemsCount());
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnPhoneStatusSnapshotReceivedWithCameraRollSettingDisabled) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key2");
@@ -437,7 +440,7 @@
   EXPECT_EQ(0, GetCurrentItemsCount());
 }
 
-TEST_F(CameraRollManagerTest,
+TEST_F(CameraRollManagerImplTest,
        OnPhoneStatusSnapshotReceivedWithoutStoragePermission) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key2");
@@ -457,7 +460,7 @@
   EXPECT_EQ(0, GetCurrentItemsCount());
 }
 
-TEST_F(CameraRollManagerTest, OnFeatureOnFeatureStatesChangedToDisabled) {
+TEST_F(CameraRollManagerImplTest, OnFeatureOnFeatureStatesChangedToDisabled) {
   proto::FetchCameraRollItemsResponse response;
   PopulateItemProto(response.add_items(), "key2");
   PopulateItemProto(response.add_items(), "key1");
diff --git a/chromeos/components/phonehub/fake_camera_roll_manager.cc b/chromeos/components/phonehub/fake_camera_roll_manager.cc
new file mode 100644
index 0000000..a76ae42
--- /dev/null
+++ b/chromeos/components/phonehub/fake_camera_roll_manager.cc
@@ -0,0 +1,15 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromeos/components/phonehub/fake_camera_roll_manager.h"
+
+namespace chromeos {
+namespace phonehub {
+
+FakeCameraRollManager::FakeCameraRollManager() = default;
+
+FakeCameraRollManager::~FakeCameraRollManager() = default;
+
+}  // namespace phonehub
+}  // namespace chromeos
diff --git a/chromeos/components/phonehub/fake_camera_roll_manager.h b/chromeos/components/phonehub/fake_camera_roll_manager.h
new file mode 100644
index 0000000..7553f858
--- /dev/null
+++ b/chromeos/components/phonehub/fake_camera_roll_manager.h
@@ -0,0 +1,26 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_COMPONENTS_PHONEHUB_FAKE_CAMERA_ROLL_MANAGER_H_
+#define CHROMEOS_COMPONENTS_PHONEHUB_FAKE_CAMERA_ROLL_MANAGER_H_
+
+#include "chromeos/components/phonehub/camera_roll_manager.h"
+
+namespace chromeos {
+namespace phonehub {
+
+class FakeCameraRollManager : public CameraRollManager {
+ public:
+  FakeCameraRollManager();
+  ~FakeCameraRollManager() override;
+
+  using CameraRollManager::SetCurrentItems;
+
+  using CameraRollManager::ClearCurrentItems;
+};
+
+}  // namespace phonehub
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_PHONEHUB_FAKE_CAMERA_ROLL_MANAGER_H_
diff --git a/chromeos/components/phonehub/fake_phone_hub_manager.cc b/chromeos/components/phonehub/fake_phone_hub_manager.cc
index fa3ba1f..91ca62a 100644
--- a/chromeos/components/phonehub/fake_phone_hub_manager.cc
+++ b/chromeos/components/phonehub/fake_phone_hub_manager.cc
@@ -17,6 +17,11 @@
   return &fake_browser_tabs_model_provider_;
 }
 
+CameraRollManager* FakePhoneHubManager::GetCameraRollManager() {
+  return features::IsPhoneHubCameraRollEnabled() ? &fake_camera_roll_manager_
+                                                 : nullptr;
+}
+
 DoNotDisturbController* FakePhoneHubManager::GetDoNotDisturbController() {
   return &fake_do_not_disturb_controller_;
 }
diff --git a/chromeos/components/phonehub/fake_phone_hub_manager.h b/chromeos/components/phonehub/fake_phone_hub_manager.h
index 8d76089..093998e 100644
--- a/chromeos/components/phonehub/fake_phone_hub_manager.h
+++ b/chromeos/components/phonehub/fake_phone_hub_manager.h
@@ -6,6 +6,7 @@
 #define CHROMEOS_COMPONENTS_PHONEHUB_FAKE_PHONE_HUB_MANAGER_H_
 
 #include "chromeos/components/phonehub/fake_browser_tabs_model_provider.h"
+#include "chromeos/components/phonehub/fake_camera_roll_manager.h"
 #include "chromeos/components/phonehub/fake_connection_scheduler.h"
 #include "chromeos/components/phonehub/fake_do_not_disturb_controller.h"
 #include "chromeos/components/phonehub/fake_feature_status_provider.h"
@@ -84,9 +85,14 @@
     return &fake_browser_tabs_model_provider_;
   }
 
+  FakeCameraRollManager* fake_camera_roll_manager() {
+    return &fake_camera_roll_manager_;
+  }
+
  private:
   // PhoneHubManager:
   BrowserTabsModelProvider* GetBrowserTabsModelProvider() override;
+  CameraRollManager* GetCameraRollManager() override;
   DoNotDisturbController* GetDoNotDisturbController() override;
   FeatureStatusProvider* GetFeatureStatusProvider() override;
   FindMyDeviceController* GetFindMyDeviceController() override;
@@ -115,6 +121,7 @@
   FakeConnectionScheduler fake_connection_scheduler_;
   FakeUserActionRecorder fake_user_action_recorder_;
   FakeBrowserTabsModelProvider fake_browser_tabs_model_provider_;
+  FakeCameraRollManager fake_camera_roll_manager_;
 };
 
 }  // namespace phonehub
diff --git a/chromeos/components/phonehub/phone_hub_manager.h b/chromeos/components/phonehub/phone_hub_manager.h
index ee7b198..e859344 100644
--- a/chromeos/components/phonehub/phone_hub_manager.h
+++ b/chromeos/components/phonehub/phone_hub_manager.h
@@ -10,6 +10,8 @@
 namespace chromeos {
 namespace phonehub {
 
+class BrowserTabsModelProvider;
+class CameraRollManager;
 class ConnectionScheduler;
 class DoNotDisturbController;
 class FeatureStatusProvider;
@@ -23,7 +25,6 @@
 class ScreenLockManager;
 class TetherController;
 class UserActionRecorder;
-class BrowserTabsModelProvider;
 
 // Responsible for the core logic of the Phone Hub feature and exposes
 // interfaces via its public API. This class is intended to be a singleton.
@@ -36,6 +37,7 @@
 
   // Getters for sub-elements.
   virtual BrowserTabsModelProvider* GetBrowserTabsModelProvider() = 0;
+  virtual CameraRollManager* GetCameraRollManager() = 0;
   virtual ConnectionScheduler* GetConnectionScheduler() = 0;
   virtual DoNotDisturbController* GetDoNotDisturbController() = 0;
   virtual FeatureStatusProvider* GetFeatureStatusProvider() = 0;
diff --git a/chromeos/components/phonehub/phone_hub_manager_impl.cc b/chromeos/components/phonehub/phone_hub_manager_impl.cc
index 6ca059d4..6fa731306 100644
--- a/chromeos/components/phonehub/phone_hub_manager_impl.cc
+++ b/chromeos/components/phonehub/phone_hub_manager_impl.cc
@@ -8,7 +8,7 @@
 #include "chromeos/components/phonehub/browser_tabs_metadata_fetcher.h"
 #include "chromeos/components/phonehub/browser_tabs_model_controller.h"
 #include "chromeos/components/phonehub/browser_tabs_model_provider.h"
-#include "chromeos/components/phonehub/camera_roll_manager.h"
+#include "chromeos/components/phonehub/camera_roll_manager_impl.h"
 #include "chromeos/components/phonehub/connection_scheduler_impl.h"
 #include "chromeos/components/phonehub/cros_state_sender.h"
 #include "chromeos/components/phonehub/do_not_disturb_controller_impl.h"
@@ -144,12 +144,12 @@
           std::make_unique<InvalidConnectionDisconnector>(
               connection_manager_.get(),
               phone_model_.get())),
-      camera_roll_manager_(
-          features::IsPhoneHubCameraRollEnabled()
-              ? std::make_unique<CameraRollManager>(message_receiver_.get(),
-                                                    message_sender_.get(),
-                                                    multidevice_setup_client)
-              : nullptr) {}
+      camera_roll_manager_(features::IsPhoneHubCameraRollEnabled()
+                               ? std::make_unique<CameraRollManagerImpl>(
+                                     message_receiver_.get(),
+                                     message_sender_.get(),
+                                     multidevice_setup_client)
+                               : nullptr) {}
 
 PhoneHubManagerImpl::~PhoneHubManagerImpl() = default;
 
@@ -157,6 +157,10 @@
   return browser_tabs_model_provider_.get();
 }
 
+CameraRollManager* PhoneHubManagerImpl::GetCameraRollManager() {
+  return camera_roll_manager_.get();
+}
+
 ConnectionScheduler* PhoneHubManagerImpl::GetConnectionScheduler() {
   return connection_scheduler_.get();
 }
diff --git a/chromeos/components/phonehub/phone_hub_manager_impl.h b/chromeos/components/phonehub/phone_hub_manager_impl.h
index 1220619..b5255fe7 100644
--- a/chromeos/components/phonehub/phone_hub_manager_impl.h
+++ b/chromeos/components/phonehub/phone_hub_manager_impl.h
@@ -58,6 +58,7 @@
 
   // PhoneHubManager:
   BrowserTabsModelProvider* GetBrowserTabsModelProvider() override;
+  CameraRollManager* GetCameraRollManager() override;
   ConnectionScheduler* GetConnectionScheduler() override;
   DoNotDisturbController* GetDoNotDisturbController() override;
   FeatureStatusProvider* GetFeatureStatusProvider() override;
diff --git a/chromeos/components/phonehub/proto/phonehub_api.proto b/chromeos/components/phonehub/proto/phonehub_api.proto
index 81dc2c16..527dee8b 100644
--- a/chromeos/components/phonehub/proto/phonehub_api.proto
+++ b/chromeos/components/phonehub/proto/phonehub_api.proto
@@ -245,7 +245,8 @@
 
 message ShowNotificationAccessSetupResponse {}
 
-// Next ID: 6
+// When adding new fields to this message, update CameraRollItem#operator==
+// Located in /chromeos/components/phonehub/camera_roll_item.cc
 message CameraRollItemMetadata {
   // A unique and stable identifier for camera roll items on the Android device.
   string key = 1;
@@ -253,6 +254,7 @@
   string mime_type = 2;
   int64 last_modified_millis = 3;
   int64 file_size_bytes = 4;
+  // Next ID: 6
 }
 
 // Contains data needed to display the thumbnail of a camera roll item.
diff --git a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
index 3c87e58..b9552a1 100644
--- a/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
+++ b/chromeos/services/cros_healthd/public/mojom/cros_healthd_probe.mojom
@@ -308,6 +308,14 @@
   array<PhysicalCpuInfo> physical_cpus;
   // Information about the CPU temperature channels.
   array<CpuTemperatureChannel> temperature_channels;
+  // Information about keylocker.
+  KeylockerInfo? keylocker_info;
+};
+
+// Information related to Keylocker.
+struct KeylockerInfo {
+  // Has Keylocker been configured or not.
+  bool keylocker_configured;
 };
 
 // Information related to a particular physical CPU.
diff --git a/chromeos/services/multidevice_setup/feature_state_manager_impl.cc b/chromeos/services/multidevice_setup/feature_state_manager_impl.cc
index 09f30cff..c07f61b 100644
--- a/chromeos/services/multidevice_setup/feature_state_manager_impl.cc
+++ b/chromeos/services/multidevice_setup/feature_state_manager_impl.cc
@@ -572,6 +572,15 @@
       return true;
     }
 
+    // Edge Case: Eche is considered activated on the host when Phone Hub is
+    // enabled and Eche's state is kSupported or kEnabled.
+    if (feature == mojom::Feature::kEche) {
+      return feature_state == multidevice::SoftwareFeatureState::kSupported &&
+             host_device.GetSoftwareFeatureState(
+                 multidevice::SoftwareFeature::kPhoneHubHost) ==
+                 multidevice::SoftwareFeatureState::kEnabled;
+    }
+
     // Edge Case: Wifi Sync is considered activated on host when the state is
     // kSupported or kEnabled. kEnabled/kSupported correspond to on/off for Wifi
     // Sync Host.
diff --git a/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc b/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc
index 6e78bb9..4103b21 100644
--- a/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc
+++ b/chromeos/services/multidevice_setup/feature_state_manager_impl_unittest.cc
@@ -877,7 +877,7 @@
   // Together users; they must go to settings to explicitly enable PhoneHub.
   SetSoftwareFeatureState(false /* use_local_device */,
                           multidevice::SoftwareFeature::kEcheHost,
-                          multidevice::SoftwareFeatureState::kEnabled);
+                          multidevice::SoftwareFeatureState::kSupported);
   VerifyFeatureState(mojom::FeatureState::kUnavailableTopLevelFeatureDisabled,
                      mojom::Feature::kEche);
   VerifyFeatureStateChange(
diff --git a/chromeos/settings/cros_settings_names.cc b/chromeos/settings/cros_settings_names.cc
index c8cebd7..9406a8e 100644
--- a/chromeos/settings/cros_settings_names.cc
+++ b/chromeos/settings/cros_settings_names.cc
@@ -210,6 +210,37 @@
 const char kReportRunningKioskApp[] =
     "cros.device_status.report_running_kiosk_app";
 
+const char* const kDeviceReportingSettings[] = {
+    kReportDeviceVersionInfo,
+    kReportDeviceActivityTimes,
+    kReportDeviceAudioStatus,
+    kReportDeviceBoardStatus,
+    kReportDeviceBootMode,
+    kReportDeviceCpuInfo,
+    kReportDeviceTimezoneInfo,
+    kReportDeviceMemoryInfo,
+    kReportDeviceBacklightInfo,
+    kReportDeviceLocation,
+    kReportDeviceNetworkConfiguration,
+    kReportDeviceNetworkInterfaces,
+    kReportDeviceNetworkStatus,
+    kReportDevicePowerStatus,
+    kReportDeviceStorageStatus,
+    kReportDeviceUsers,
+    kReportDeviceHardwareStatus,
+    kReportDeviceSessionStatus,
+    kReportDeviceGraphicsStatus,
+    kReportDeviceCrashReportInfo,
+    kReportOsUpdateStatus,
+    kReportRunningKioskApp,
+    kReportDeviceAppInfo,
+    kReportDeviceBluetoothInfo,
+    kReportDeviceFanInfo,
+    kReportDeviceVpdInfo,
+    kReportDeviceSystemInfo,
+    kReportDevicePrintJobs,
+    kReportDeviceLoginLogout};
+
 // How frequently device status reports are uploaded, in milliseconds.
 const char kReportUploadFrequency[] =
     "cros.device_status.report_upload_frequency";
diff --git a/chromeos/settings/cros_settings_names.h b/chromeos/settings/cros_settings_names.h
index 3f91560..58a59c7 100644
--- a/chromeos/settings/cros_settings_names.h
+++ b/chromeos/settings/cros_settings_names.h
@@ -133,6 +133,9 @@
 COMPONENT_EXPORT(CHROMEOS_SETTINGS)
 extern const char kReportDeviceLoginLogout[];
 
+COMPONENT_EXPORT(CHROMEOS_SETTINGS)
+extern const char* const kDeviceReportingSettings[];
+
 COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kHeartbeatEnabled[];
 COMPONENT_EXPORT(CHROMEOS_SETTINGS) extern const char kHeartbeatFrequency[];
 
diff --git a/components/arc/arc_features.cc b/components/arc/arc_features.cc
index e8a0d3a..a41f149 100644
--- a/components/arc/arc_features.cc
+++ b/components/arc/arc_features.cc
@@ -91,6 +91,10 @@
 const base::Feature kRtVcpuQuadCore{"ArcRtVcpuQuadCore",
                                     base::FEATURE_ENABLED_BY_DEFAULT};
 
+// When enabled, unclaimed USB device will be attached to ARCVM by default.
+const base::Feature kUsbDeviceDefaultAttachToArcVm{
+    "UsbDeviceDefaultAttachToArcVm", base::FEATURE_DISABLED_BY_DEFAULT};
+
 // Controls ARC high-memory dalvik profile in ARCVM.
 // When enabled, Android tries to use dalvik memory profile tuned for
 // high-memory devices like 8G and 16G. This is enabled without conditions
diff --git a/components/arc/arc_features.h b/components/arc/arc_features.h
index 968f1ac..781372e 100644
--- a/components/arc/arc_features.h
+++ b/components/arc/arc_features.h
@@ -33,6 +33,7 @@
 extern const base::Feature kRtVcpuDualCore;
 extern const base::Feature kRtVcpuQuadCore;
 extern const base::Feature kSaveRawFilesOnTracing;
+extern const base::Feature kUsbDeviceDefaultAttachToArcVm;
 extern const base::Feature kUseHighMemoryDalvikProfile;
 extern const base::Feature kUsbStorageUIFeature;
 extern const base::Feature kVideoDecoder;
diff --git a/components/arc/usb/usb_host_bridge.cc b/components/arc/usb/usb_host_bridge.cc
index bab6330..e430a8e6 100644
--- a/components/arc/usb/usb_host_bridge.cc
+++ b/components/arc/usb/usb_host_bridge.cc
@@ -243,9 +243,6 @@
 }
 
 void ArcUsbHostBridge::OnConnectionReady() {
-  if (delegate_)
-    delegate_->AttachDevicesToArcVm();
-
   // Receive mojo::Remote<UsbDeviceManager> from DeviceService.
   content::GetDeviceService().BindUsbDeviceManager(
       usb_manager_.BindNewPipeAndPassReceiver());
@@ -275,6 +272,8 @@
   ui_delegate_ = ui_delegate;
 }
 
+// TODO(lgcheng) Remove these part. For ARCVM the usb_host_bridge will not be
+// connected.
 void ArcUsbHostBridge::SetDelegate(std::unique_ptr<Delegate> delegate) {
   delegate_ = std::move(delegate);
 }
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index f14fa3bb..f692bdc 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1471,8 +1471,8 @@
     if (!IsAutofillableElement(control_element))
       continue;
 
-    form->fields.push_back(FormFieldData());
-    shadow_fields.push_back(ShadowFieldData());
+    form->fields.emplace_back();
+    shadow_fields.emplace_back();
     WebFormControlElementToFormField(
         form->unique_renderer_id, control_element, field_data_manager,
         extract_mask, &form->fields.back(), &shadow_fields.back());
@@ -1909,8 +1909,7 @@
 std::vector<blink::WebFormControlElement> ExtractAutofillableElementsFromSet(
     const WebVector<WebFormControlElement>& control_elements) {
   std::vector<blink::WebFormControlElement> autofillable_elements;
-  for (size_t i = 0; i < control_elements.size(); ++i) {
-    WebFormControlElement element = control_elements[i];
+  for (const auto& element : control_elements) {
     if (!IsAutofillableElement(element))
       continue;
 
@@ -2056,10 +2055,10 @@
     const WebSelectElement select_element = element.ToConst<WebSelectElement>();
     // Convert the |select_element| value to text if requested.
     WebVector<WebElement> list_items = select_element.GetListItems();
-    for (size_t i = 0; i < list_items.size(); ++i) {
-      if (IsOptionElement(list_items[i])) {
+    for (const auto& list_item : list_items) {
+      if (IsOptionElement(list_item)) {
         const WebOptionElement option_element =
-            list_items[i].ToConst<WebOptionElement>();
+            list_item.ToConst<WebOptionElement>();
         if (option_element.Value().Utf16() == value) {
           value = option_element.GetText().Utf16();
           break;
diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc
index 8704b9f..135a6a2 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -26,6 +26,7 @@
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
 #include "components/autofill/content/common/mojom/autofill_driver.mojom.h"
+#include "components/autofill/content/renderer/form_autofill_util.h"
 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
 #include "components/autofill/content/renderer/password_generation_agent.h"
 #include "components/autofill/content/renderer/prefilled_values_detector.h"
@@ -1257,7 +1258,7 @@
     if (!sent_request_to_store_ && password_forms_data.empty() &&
         HasPasswordField(*frame)) {
       // Set everything that |FormDigest| needs.
-      password_forms_data.push_back(FormData());
+      password_forms_data.emplace_back();
     }
     if (!password_forms_data.empty()) {
       sent_request_to_store_ = true;
@@ -1593,6 +1594,8 @@
     const WebInputElement& user_input,
     ShowAll show_all,
     OnPasswordField show_on_password_field) {
+  constexpr char kAutocompleteAttribute[] = "autocomplete";
+  constexpr char kAutocompleteWebAuthn[] = "webauthn";
   username_query_prefix_ = typed_username;
   FormData form;
   FormFieldData field;
@@ -1604,6 +1607,8 @@
     options |= SHOW_ALL;
   if (show_on_password_field)
     options |= IS_PASSWORD_FIELD;
+  if (user_input.GetAttribute(kAutocompleteAttribute) == kAutocompleteWebAuthn)
+    options |= ACCEPTS_WEBAUTHN_CREDENTIALS;
 
   GetPasswordManagerDriver().ShowPasswordSuggestions(
       field.text_direction, typed_username, options,
diff --git a/components/autofill/core/browser/ui/popup_item_ids.h b/components/autofill/core/browser/ui/popup_item_ids.h
index 1c1c945..7105cf11 100644
--- a/components/autofill/core/browser/ui/popup_item_ids.h
+++ b/components/autofill/core/browser/ui/popup_item_ids.h
@@ -35,7 +35,8 @@
   POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_RE_SIGNIN = -24,
   POPUP_ITEM_ID_PASSWORD_ACCOUNT_STORAGE_EMPTY = -25,
   POPUP_ITEM_ID_MIXED_FORM_MESSAGE = -26,
-  POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY = -27
+  POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY = -27,
+  POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL = -28
 };
 
 }  // namespace autofill
diff --git a/components/autofill/core/common/autofill_constants.h b/components/autofill/core/common/autofill_constants.h
index 4a822bbc..7a1e157 100644
--- a/components/autofill/core/common/autofill_constants.h
+++ b/components/autofill/core/common/autofill_constants.h
@@ -74,7 +74,9 @@
 // Options bitmask values for AutofillHostMsg_ShowPasswordSuggestions IPC
 enum ShowPasswordSuggestionsOptions {
   SHOW_ALL = 1 << 0 /* show all credentials, not just ones matching username */,
-  IS_PASSWORD_FIELD = 1 << 1 /* input field is a password field */
+  IS_PASSWORD_FIELD = 1 << 1 /* input field is a password field */,
+  ACCEPTS_WEBAUTHN_CREDENTIALS =
+      1 << 2 /* input field is marked to accept webauthn credentials */,
 };
 
 // Constants for the soft/hard deletion of Autofill data.
diff --git a/components/browser_ui/styles/android/java/res/values/styles.xml b/components/browser_ui/styles/android/java/res/values/styles.xml
index 54d9b8a..8cf5604 100644
--- a/components/browser_ui/styles/android/java/res/values/styles.xml
+++ b/components/browser_ui/styles/android/java/res/values/styles.xml
@@ -20,6 +20,7 @@
 
         <!-- Spinner styles -->
         <item name="spinnerStyle">@style/SpinnerStyle</item>
+        <item name="android:progressBarStyle">@style/ProgressBarStyle</item>
 
         <!-- Popup styles -->
         <!-- Set android popup menu attributes for context menu styles because the context menus are
@@ -130,6 +131,10 @@
         <item name="android:paddingTop">10dp</item>
     </style>
 
+    <style name="ProgressBarStyle" parent="Widget.AppCompat.ProgressBar">
+        <item name="android:indeterminateTint">?attr/default_icon_color_accent1</item>
+    </style>
+
     <!-- Spinner styles -->
     <style name="SpinnerStyle" parent="Widget.AppCompat.Spinner">
         <item name="android:popupBackground">@drawable/dialog_bg_tinted</item>
diff --git a/components/browser_ui/styles/android/java/res/values/themes.xml b/components/browser_ui/styles/android/java/res/values/themes.xml
index d112329..894a01d 100644
--- a/components/browser_ui/styles/android/java/res/values/themes.xml
+++ b/components/browser_ui/styles/android/java/res/values/themes.xml
@@ -65,6 +65,9 @@
         <item name="default_icon_color_secondary">@color/default_icon_color_secondary_dark</item>
         <item name="default_icon_color_disabled">@color/default_icon_color_disabled_dark</item>
         <item name="default_icon_color_disabled_inverse">@color/default_icon_color_disabled_light</item>
+        <item name="default_icon_color_accent1">?attr/colorPrimary</item>
+        <!-- Common text colors. -->
+        <item name="default_text_color_accent1">?attr/colorPrimary</item>
     </style>
 
     <style name="Base.V31.Theme.BrowserUI" parent="Base.V21.Theme.BrowserUI" />
diff --git a/components/embedder_support/android/metrics/BUILD.gn b/components/embedder_support/android/metrics/BUILD.gn
index 5903aaf..a77cc947 100644
--- a/components/embedder_support/android/metrics/BUILD.gn
+++ b/components/embedder_support/android/metrics/BUILD.gn
@@ -21,6 +21,7 @@
   deps = [
     ":jni",
     "//base",
+    "//cc/base",
     "//components/metrics",
     "//components/metrics:content",
     "//components/metrics:net",
diff --git a/components/embedder_support/android/metrics/DEPS b/components/embedder_support/android/metrics/DEPS
index c96cb27..aef2f182 100644
--- a/components/embedder_support/android/metrics/DEPS
+++ b/components/embedder_support/android/metrics/DEPS
@@ -8,3 +8,9 @@
   "+services/network/public/cpp",
   "+services/resource_coordinator/public/cpp/memory_instrumentation",
 ]
+
+specific_include_rules = {
+  "components/embedder_support/android/metrics/android_metrics_service_client\.cc": [
+    "+cc/base/switches.h",
+  ],
+}
diff --git a/components/embedder_support/android/metrics/android_metrics_service_client.cc b/components/embedder_support/android/metrics/android_metrics_service_client.cc
index 5558ffb..2f6a491 100644
--- a/components/embedder_support/android/metrics/android_metrics_service_client.cc
+++ b/components/embedder_support/android/metrics/android_metrics_service_client.cc
@@ -22,6 +22,7 @@
 #include "base/task/thread_pool.h"
 #include "base/threading/thread_restrictions.h"
 #include "build/build_config.h"
+#include "cc/base/switches.h"
 #include "components/embedder_support/android/metrics/android_metrics_log_uploader.h"
 #include "components/embedder_support/android/metrics/jni/AndroidMetricsServiceClient_jni.h"
 #include "components/metrics/android_metrics_provider.h"
@@ -250,7 +251,8 @@
   // unique experiment combinations. This is better for privacy (since
   // experiment state doesn't identify users), but also means fewer combinations
   // are tested in the wild.
-  metrics_state_manager_->InstantiateFieldTrialList(EntropyProviderType::kLow);
+  metrics_state_manager_->InstantiateFieldTrialList(
+      cc::switches::kEnableGpuBenchmarking, EntropyProviderType::kLow);
 
   init_finished_ = true;
 
diff --git a/components/exo/data_offer_unittest.cc b/components/exo/data_offer_unittest.cc
index 1be2faf..4952032 100644
--- a/components/exo/data_offer_unittest.cc
+++ b/components/exo/data_offer_unittest.cc
@@ -11,6 +11,7 @@
 #include <string>
 #include <vector>
 
+#include "base/callback_forward.h"
 #include "base/containers/flat_set.h"
 #include "base/files/file_util.h"
 #include "base/macros.h"
@@ -99,10 +100,10 @@
                       content::RenderFrameHost* web_contents,
                       base::OnceCallback<void(bool)> callback) override {}
 
-  bool IsDragDropAllowed(const ui::DataTransferEndpoint* const data_src,
-                         const ui::DataTransferEndpoint* const data_dst,
-                         const bool is_drop) override {
-    return true;
+  void DropIfAllowed(const ui::DataTransferEndpoint* const data_src,
+                     const ui::DataTransferEndpoint* const data_dst,
+                     base::OnceClosure drop_cb) override {
+    std::move(drop_cb).Run();
   }
 
   ui::EndpointType last_src_type_ = ui::EndpointType::kUnknownVm;
diff --git a/components/metrics/metrics_state_manager.cc b/components/metrics/metrics_state_manager.cc
index f238bcf6..0782473e 100644
--- a/components/metrics/metrics_state_manager.cc
+++ b/components/metrics/metrics_state_manager.cc
@@ -13,6 +13,7 @@
 
 #include "base/callback_helpers.h"
 #include "base/check.h"
+#include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/debug/leak_annotations.h"
 #include "base/guid.h"
@@ -35,11 +36,11 @@
 #include "components/prefs/pref_service.h"
 #include "components/variations/entropy_provider.h"
 #include "components/variations/pref_names.h"
+#include "components/variations/variations_switches.h"
 #include "third_party/metrics_proto/chrome_user_metrics_extension.pb.h"
 #include "third_party/metrics_proto/system_profile.pb.h"
 
 namespace metrics {
-
 namespace {
 
 // The argument used to generate a non-identifying entropy source. We want no
@@ -268,6 +269,7 @@
 }
 
 void MetricsStateManager::InstantiateFieldTrialList(
+    const char* enable_gpu_benchmarking_switch,
     EntropyProviderType entropy_provider_type) {
   // Instantiate the FieldTrialList to support field trials. If an instance
   // already exists, this is likely a test scenario with a ScopedFeatureList, so
@@ -285,6 +287,19 @@
     ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list);
     ignore_result(leaked_field_trial_list);
   }
+
+  // When benchmarking is enabled, field trials' default groups are chosen, so
+  // see whether benchmarking needs to be enabled here, before any field trials
+  // are created.
+  const base::CommandLine* command_line =
+      base::CommandLine::ForCurrentProcess();
+  // TODO(crbug/1251680): See whether it's possible to consolidate the switches.
+  if (command_line->HasSwitch(variations::switches::kEnableBenchmarking) ||
+      (enable_gpu_benchmarking_switch &&
+       command_line->HasSwitch(enable_gpu_benchmarking_switch))) {
+    base::FieldTrial::EnableBenchmarking();
+  }
+
   // Initializing the CleanExitBeacon is done after FieldTrialList instantiation
   // to allow experimentation on the CleanExitBeacon.
   clean_exit_beacon_.Initialize();
diff --git a/components/metrics/metrics_state_manager.h b/components/metrics/metrics_state_manager.h
index 7d4cccdf..a9221c8f 100644
--- a/components/metrics/metrics_state_manager.h
+++ b/components/metrics/metrics_state_manager.h
@@ -106,14 +106,17 @@
     return startup_visibility_ == StartupVisibility::kForeground;
   }
 
-  // Instantiates the FieldTrialList. Uses |entropy_provider_type| to determine
-  // the type of EntropyProvider to use for one-time randomization. See
-  // CreateLowEntropyProvider() and CreateDefaultEntropyProvider() for more
-  // details.
+  // Instantiates the FieldTrialList. Uses |enable_gpu_benchmarking_switch| to
+  // set up the FieldTrialList for benchmarking runs. Uses
+  // |entropy_provider_type| to determine the type of EntropyProvider to use for
+  // one-time randomization. See CreateLowEntropyProvider() and
+  // CreateDefaultEntropyProvider() for more details.
   //
   // Side effect: Initializes |clean_exit_beacon_|.
-  void InstantiateFieldTrialList(EntropyProviderType entropy_provider_type =
-                                     EntropyProviderType::kDefault);
+  void InstantiateFieldTrialList(
+      const char* enable_gpu_benchmarking_switch = nullptr,
+      EntropyProviderType entropy_provider_type =
+          EntropyProviderType::kDefault);
 
   // Signals whether the session has shutdown cleanly if |update_beacon| is
   // true. Passing `false` for |has_session_shutdown_cleanly| means that Chrome
diff --git a/components/metrics_services_manager/metrics_services_manager.cc b/components/metrics_services_manager/metrics_services_manager.cc
index 4ca08447..0511100 100644
--- a/components/metrics_services_manager/metrics_services_manager.cc
+++ b/components/metrics_services_manager/metrics_services_manager.cc
@@ -37,13 +37,14 @@
 
 MetricsServicesManager::~MetricsServicesManager() {}
 
-void MetricsServicesManager::InstantiateFieldTrialList() const {
+void MetricsServicesManager::InstantiateFieldTrialList(
+    const char* enable_gpu_benchmarking_switch) const {
 #if BUILDFLAG(IS_CHROMEOS_ASH)
   metrics::structured::NeutrinoDevicesLog(
       metrics::structured::NeutrinoDevicesLocation::kCreateEntropyProvider);
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
   client_->GetMetricsStateManager()->InstantiateFieldTrialList(
-      metrics::EntropyProviderType::kDefault);
+      enable_gpu_benchmarking_switch, metrics::EntropyProviderType::kDefault);
 }
 
 metrics::MetricsService* MetricsServicesManager::GetMetricsService() {
diff --git a/components/metrics_services_manager/metrics_services_manager.h b/components/metrics_services_manager/metrics_services_manager.h
index cc490e8..514644f 100644
--- a/components/metrics_services_manager/metrics_services_manager.h
+++ b/components/metrics_services_manager/metrics_services_manager.h
@@ -47,9 +47,12 @@
   virtual ~MetricsServicesManager();
 
   // Instantiates the FieldTrialList using Chrome's default entropy provider.
+  // Uses |enable_gpu_benchmarking_switch| to set up the FieldTrialList for
+  // benchmarking runs.
   //
   // Side effect: Initializes the CleanExitBeacon.
-  void InstantiateFieldTrialList() const;
+  void InstantiateFieldTrialList(
+      const char* enable_gpu_benchmarking_switch = nullptr) const;
 
   // Returns the MetricsService, creating it if it hasn't been created yet (and
   // additionally creating the MetricsServiceClient in that case).
diff --git a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoFeatures.java b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoFeatures.java
index 37cbaff3e..4e2f8e1 100644
--- a/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoFeatures.java
+++ b/components/page_info/android/java/src/org/chromium/components/page_info/PageInfoFeatures.java
@@ -18,10 +18,13 @@
 @MainDex
 public class PageInfoFeatures extends Features {
     public static final String PAGE_INFO_HISTORY_NAME = "PageInfoHistory";
+    public static final String PAGE_INFO_STORE_INFO_NAME = "PageInfoStoreInfo";
 
     // This list must be kept in sync with kFeaturesExposedToJava in page_info_features.cc.
     public static final PageInfoFeatures PAGE_INFO_HISTORY =
             new PageInfoFeatures(0, PAGE_INFO_HISTORY_NAME);
+    public static final PageInfoFeatures PAGE_INFO_STORE_INFO =
+            new PageInfoFeatures(1, PAGE_INFO_STORE_INFO_NAME);
 
     private final int mOrdinal;
 
diff --git a/components/page_info/android/page_info_features.cc b/components/page_info/android/page_info_features.cc
index d6fe694..91f7c5e 100644
--- a/components/page_info/android/page_info_features.cc
+++ b/components/page_info/android/page_info_features.cc
@@ -16,6 +16,7 @@
 // replicated in the same order in PageInfoFeatures.java.
 const base::Feature* kFeaturesExposedToJava[] = {
     &kPageInfoHistory,
+    &kPageInfoStoreInfo,
 };
 
 }  // namespace
diff --git a/components/page_info/features.cc b/components/page_info/features.cc
index 4db4461..93f11b3 100644
--- a/components/page_info/features.cc
+++ b/components/page_info/features.cc
@@ -12,6 +12,8 @@
 #if defined(OS_ANDROID)
 const base::Feature kPageInfoHistory{"PageInfoHistory",
                                      base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kPageInfoStoreInfo{"PageInfoStoreInfo",
+                                       base::FEATURE_DISABLED_BY_DEFAULT};
 #endif
 
 #if !defined(OS_ANDROID)
diff --git a/components/page_info/features.h b/components/page_info/features.h
index 72eef2c..32a4b9d 100644
--- a/components/page_info/features.h
+++ b/components/page_info/features.h
@@ -16,6 +16,8 @@
 #if defined(OS_ANDROID)
 // Enables the history sub page for Page Info.
 extern const base::Feature kPageInfoHistory;
+// Enables the store info row for Page Info.
+extern const base::Feature kPageInfoStoreInfo;
 #endif
 
 #if !defined(OS_ANDROID)
diff --git a/components/page_info/page_info.h b/components/page_info/page_info.h
index 560e75a..cb4e5d1 100644
--- a/components/page_info/page_info.h
+++ b/components/page_info/page_info.h
@@ -148,6 +148,7 @@
     PAGE_INFO_SAFETY_TIP_HELP_OPENED = 24,
     PAGE_INFO_CHOOSER_OBJECT_DELETED = 25,
     PAGE_INFO_RESET_DECISIONS_CLICKED = 26,
+    PAGE_INFO_STORE_INFO_CLICKED = 27,
     PAGE_INFO_COUNT
   };
 
diff --git a/components/password_manager/core/browser/BUILD.gn b/components/password_manager/core/browser/BUILD.gn
index 25910ef10..936de2f 100644
--- a/components/password_manager/core/browser/BUILD.gn
+++ b/components/password_manager/core/browser/BUILD.gn
@@ -244,6 +244,7 @@
     "ui/saved_passwords_presenter.h",
     "votes_uploader.cc",
     "votes_uploader.h",
+    "webauthn_credentials_delegate.h",
     "well_known_change_password_state.cc",
     "well_known_change_password_state.h",
     "well_known_change_password_util.cc",
diff --git a/components/password_manager/core/browser/form_parsing/form_parser.cc b/components/password_manager/core/browser/form_parsing/form_parser.cc
index 4fe476855..07263d1 100644
--- a/components/password_manager/core/browser/form_parsing/form_parser.cc
+++ b/components/password_manager/core/browser/form_parsing/form_parser.cc
@@ -24,6 +24,7 @@
 #include "components/autofill/core/browser/autofill_regex_constants.h"
 #include "components/autofill/core/browser/autofill_regexes.h"
 #include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/common/autofill_constants.h"
 #include "components/autofill/core/common/form_data.h"
 #include "components/autofill/core/common/unique_ids.h"
 #include "components/password_manager/core/browser/password_form.h"
diff --git a/components/password_manager/core/browser/leak_detection_delegate.cc b/components/password_manager/core/browser/leak_detection_delegate.cc
index 8426bd4..a0babc6 100644
--- a/components/password_manager/core/browser/leak_detection_delegate.cc
+++ b/components/password_manager/core/browser/leak_detection_delegate.cc
@@ -99,7 +99,14 @@
     IsSaved is_saved,
     IsReused is_reused,
     GURL url,
-    std::u16string username) {
+    std::u16string username,
+    std::vector<GURL> all_urls_with_leaked_credentials) {
+  std::vector<std::pair<GURL, std::u16string>> identities;
+  for (const auto& u : all_urls_with_leaked_credentials) {
+    identities.emplace_back(u, username);
+  }
+  client_->MaybeReportEnterprisePasswordBreachEvent(identities);
+
   bool force_dialog_for_testing = base::GetFieldTrialParamByFeatureAsBool(
       password_manager::features::kPasswordChange,
       password_manager::features::
diff --git a/components/password_manager/core/browser/leak_detection_delegate.h b/components/password_manager/core/browser/leak_detection_delegate.h
index 8731e3f9..46106b1 100644
--- a/components/password_manager/core/browser/leak_detection_delegate.h
+++ b/components/password_manager/core/browser/leak_detection_delegate.h
@@ -53,10 +53,14 @@
 
   // Initiates the showing of the leak detection notification. It is called by
   // |helper_| after |is_saved|/|is_reused| was asynchronously determined.
-  void OnShowLeakDetectionNotification(IsSaved is_saved,
-                                       IsReused is_reused,
-                                       GURL url,
-                                       std::u16string username);
+  // |all_urls_with_leaked_credentials| contains all the URLs on which the
+  // leaked username/password pair is used.
+  void OnShowLeakDetectionNotification(
+      IsSaved is_saved,
+      IsReused is_reused,
+      GURL url,
+      std::u16string username,
+      std::vector<GURL> all_urls_with_leaked_credentials);
 
   void OnError(LeakDetectionError error) override;
 
diff --git a/components/password_manager/core/browser/leak_detection_delegate_helper.cc b/components/password_manager/core/browser/leak_detection_delegate_helper.cc
index 5275b5a..4e8225b 100644
--- a/components/password_manager/core/browser/leak_detection_delegate_helper.cc
+++ b/components/password_manager/core/browser/leak_detection_delegate_helper.cc
@@ -51,6 +51,7 @@
     return;
 
   std::u16string canonicalized_username = CanonicalizeUsername(username_);
+  std::vector<GURL> all_urls_with_leaked_credentials;
   for (const auto& form : partial_results_) {
     if (CanonicalizeUsername(form->username_value) == canonicalized_username &&
         form->password_value == password_) {
@@ -61,6 +62,7 @@
           InsecureType::kLeaked,
           InsecurityMetadata(base::Time::Now(), IsMuted(false)));
       store.UpdateLogin(form_to_update);
+      all_urls_with_leaked_credentials.push_back(form->url);
     }
   }
 
@@ -71,7 +73,8 @@
 
   IsReused is_reused(partial_results_.size() > (is_saved ? 1 : 0));
   std::move(callback_).Run(is_saved, is_reused, std::move(url_),
-                           std::move(username_));
+                           std::move(username_),
+                           std::move(all_urls_with_leaked_credentials));
 }
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/leak_detection_delegate_helper.h b/components/password_manager/core/browser/leak_detection_delegate_helper.h
index 36ae8d7..9d6912f 100644
--- a/components/password_manager/core/browser/leak_detection_delegate_helper.h
+++ b/components/password_manager/core/browser/leak_detection_delegate_helper.h
@@ -23,8 +23,8 @@
 class LeakDetectionDelegateHelper : public PasswordStoreConsumer {
  public:
   // Type alias for |callback_|.
-  using LeakTypeReply =
-      base::OnceCallback<void(IsSaved, IsReused, GURL, std::u16string)>;
+  using LeakTypeReply = base::OnceCallback<
+      void(IsSaved, IsReused, GURL, std::u16string, std::vector<GURL>)>;
 
   LeakDetectionDelegateHelper(
       scoped_refptr<PasswordStoreInterface> profile_store,
diff --git a/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc b/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc
index 01b39b0a..c14c5bb 100644
--- a/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc
+++ b/components/password_manager/core/browser/leak_detection_delegate_helper_unittest.cc
@@ -91,10 +91,13 @@
   }
 
   // Set the expectation for the |CredentialLeakType| in the callback_.
-  void SetOnShowLeakDetectionNotificationExpectation(IsSaved is_saved,
-                                                     IsReused is_reused) {
+  void SetOnShowLeakDetectionNotificationExpectation(
+      IsSaved is_saved,
+      IsReused is_reused,
+      std::vector<GURL> all_urls_with_leaked_credentials = {}) {
     EXPECT_CALL(callback_, Run(is_saved, is_reused, GURL(kLeakedOrigin),
-                               std::u16string(kLeakedUsername)))
+                               std::u16string(kLeakedUsername),
+                               all_urls_with_leaked_credentials))
         .Times(1);
   }
 
@@ -121,7 +124,8 @@
       CreateForm(kLeakedOrigin, kLeakedUsername)};
 
   SetGetLoginByPasswordConsumerInvocation(std::move(password_forms));
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(false));
+  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(false),
+                                                {GURL(kLeakedOrigin)});
   EXPECT_CALL(*store_, UpdateLogin);
   InitiateGetCredentialLeakType();
 }
@@ -134,7 +138,8 @@
       CreateForm(kOtherOrigin, kLeakedUsername)};
 
   SetGetLoginByPasswordConsumerInvocation(std::move(password_forms));
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(true));
+  SetOnShowLeakDetectionNotificationExpectation(
+      IsSaved(true), IsReused(true), {GURL(kLeakedOrigin), GURL(kOtherOrigin)});
   EXPECT_CALL(*store_, UpdateLogin).Times(2);
   InitiateGetCredentialLeakType();
 }
@@ -148,7 +153,8 @@
       CreateForm(kLeakedOrigin, kOtherUsername)};
 
   SetGetLoginByPasswordConsumerInvocation(std::move(password_forms));
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(true));
+  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(true),
+                                                {GURL(kLeakedOrigin)});
   EXPECT_CALL(*store_, UpdateLogin);
   InitiateGetCredentialLeakType();
 }
@@ -159,6 +165,9 @@
       CreateForm(kLeakedOrigin, kOtherUsername)};
 
   SetGetLoginByPasswordConsumerInvocation(std::move(password_forms));
+  // Don't expect anything in |all_urls_with_leaked_credentials| since it should
+  // only contain url:username pairs for which both the username and password
+  // match.
   SetOnShowLeakDetectionNotificationExpectation(IsSaved(false), IsReused(true));
   InitiateGetCredentialLeakType();
 }
@@ -169,7 +178,8 @@
       CreateForm(kOtherOrigin, kLeakedUsername)};
 
   SetGetLoginByPasswordConsumerInvocation(std::move(password_forms));
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(false), IsReused(true));
+  SetOnShowLeakDetectionNotificationExpectation(IsSaved(false), IsReused(true),
+                                                {GURL(kOtherOrigin)});
   EXPECT_CALL(*store_, UpdateLogin);
   InitiateGetCredentialLeakType();
 }
@@ -197,7 +207,8 @@
                                            other_origin_same_credential,
                                            leaked_origin_other_username});
 
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(true));
+  SetOnShowLeakDetectionNotificationExpectation(
+      IsSaved(true), IsReused(true), {GURL(kLeakedOrigin), GURL(kOtherOrigin)});
   // The expected updated forms should have leaked entries.
   leaked_origin.password_issues.insert_or_assign(
       InsecureType::kLeaked,
@@ -215,7 +226,8 @@
   PasswordForm non_canonicalized_username = CreateForm(
       kOtherOrigin, kLeakedUsernameNonCanonicalized, kLeakedPassword);
   SetGetLoginByPasswordConsumerInvocation({non_canonicalized_username});
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(false), IsReused(true));
+  SetOnShowLeakDetectionNotificationExpectation(IsSaved(false), IsReused(true),
+                                                {GURL(kOtherOrigin)});
 
   // The expected updated form should have leaked entries.
   non_canonicalized_username.password_issues.insert_or_assign(
@@ -235,7 +247,11 @@
   password_forms.back().password_value = u"another_password";
 
   SetGetLoginByPasswordConsumerInvocation(password_forms);
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(true));
+  // There's at least one set of leaked username:password on kLeakedOrigin, so
+  // it should be in |all_urls_with_leaked_credentials| even though another set
+  // of credentials on that origin has a different password.
+  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(true),
+                                                {GURL(kLeakedOrigin)});
   password_forms.at(0).password_issues.insert_or_assign(
       InsecureType::kLeaked,
       InsecurityMetadata(base::Time::Now(), IsMuted(false)));
@@ -276,7 +292,8 @@
   profile_store_->AddLogin(profile_store_form);
   account_store_->AddLogin(account_store_form);
 
-  SetOnShowLeakDetectionNotificationExpectation(IsSaved(true), IsReused(true));
+  SetOnShowLeakDetectionNotificationExpectation(
+      IsSaved(true), IsReused(true), {GURL(kLeakedOrigin), GURL(kOtherOrigin)});
 
   InitiateGetCredentialLeakType();
 
diff --git a/components/password_manager/core/browser/password_autofill_manager.cc b/components/password_manager/core/browser/password_autofill_manager.cc
index ab3c798..e47ef85 100644
--- a/components/password_manager/core/browser/password_autofill_manager.cc
+++ b/components/password_manager/core/browser/password_autofill_manager.cc
@@ -41,6 +41,7 @@
 #include "components/password_manager/core/browser/password_manager_metrics_recorder.h"
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_manager_util.h"
+#include "components/password_manager/core/browser/webauthn_credentials_delegate.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/prefs/pref_service.h"
@@ -428,6 +429,12 @@
             ? PasswordDropdownSelectedOption::kUnlockAccountStorePasswords
             : PasswordDropdownSelectedOption::kUnlockAccountStoreGeneration,
         password_client_->IsIncognito());
+  } else if (frontend_id == autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL) {
+    metrics_util::LogPasswordDropdownItemSelected(
+        PasswordDropdownSelectedOption::kWebAuthn,
+        password_client_->IsIncognito());
+    password_client_->GetWebAuthnCredentialsDelegate()
+        ->SelectWebAuthnCredential(backend_id);
   } else {
     metrics_util::LogPasswordDropdownItemSelected(
         PasswordDropdownSelectedOption::kPassword,
@@ -519,7 +526,8 @@
                                ForPasswordField(AreSuggestionForPasswordField(
                                    autofill_client_->GetPopupSuggestions())),
                                ShowAllPasswords(true), OffersGeneration(false),
-                               ShowPasswordSuggestions(true)));
+                               ShowPasswordSuggestions(true),
+                               ShowWebAuthnCredentials(false)));
 }
 
 void PasswordAutofillManager::OnNoCredentialsFound() {
@@ -552,7 +560,9 @@
       BuildSuggestions(typed_username,
                        ForPasswordField(options & autofill::IS_PASSWORD_FIELD),
                        ShowAllPasswords(options & autofill::SHOW_ALL),
-                       OffersGeneration(false), ShowPasswordSuggestions(true)));
+                       OffersGeneration(false), ShowPasswordSuggestions(true),
+                       ShowWebAuthnCredentials(
+                           options & autofill::ACCEPTS_WEBAUTHN_CREDENTIALS)));
 }
 
 bool PasswordAutofillManager::MaybeShowPasswordSuggestions(
@@ -562,7 +572,8 @@
       bounds, text_direction,
       BuildSuggestions(std::u16string(), ForPasswordField(true),
                        ShowAllPasswords(true), OffersGeneration(false),
-                       ShowPasswordSuggestions(true)));
+                       ShowPasswordSuggestions(true),
+                       ShowWebAuthnCredentials(false)));
 }
 
 bool PasswordAutofillManager::MaybeShowPasswordSuggestionsWithGeneration(
@@ -573,7 +584,8 @@
       bounds, text_direction,
       BuildSuggestions(std::u16string(), ForPasswordField(true),
                        ShowAllPasswords(true), OffersGeneration(true),
-                       ShowPasswordSuggestions(show_password_suggestions)));
+                       ShowPasswordSuggestions(show_password_suggestions),
+                       ShowWebAuthnCredentials(false)));
 }
 
 void PasswordAutofillManager::DidNavigateMainFrame() {
@@ -601,7 +613,8 @@
     ForPasswordField for_password_field,
     ShowAllPasswords show_all_passwords,
     OffersGeneration offers_generation,
-    ShowPasswordSuggestions show_password_suggestions) {
+    ShowPasswordSuggestions show_password_suggestions,
+    ShowWebAuthnCredentials show_webauthn_credentials) {
   std::vector<autofill::Suggestion> suggestions;
   bool show_account_storage_optin =
       password_client_ && password_client_->GetPasswordFeatureManager()
@@ -617,6 +630,17 @@
     return suggestions;
   }
 
+  // Add WebAuthn credentials suitable for an ongoing request if available.
+  if (show_webauthn_credentials) {
+    WebAuthnCredentialsDelegate* delegate =
+        password_client_->GetWebAuthnCredentialsDelegate();
+    DCHECK(delegate->IsWebAuthnAutofillEnabled());
+    std::vector<autofill::Suggestion> webauthn_suggestions =
+        delegate->GetWebAuthnSuggestions();
+    suggestions.insert(suggestions.end(), webauthn_suggestions.begin(),
+                       webauthn_suggestions.end());
+  }
+
   // Add password suggestions if they exist and were requested.
   if (show_password_suggestions && fill_data_) {
     GetSuggestions(*fill_data_, username_filter, page_favicon_,
@@ -715,6 +739,10 @@
 
 bool PasswordAutofillManager::PreviewSuggestion(const std::u16string& username,
                                                 int item_id) {
+  if (item_id == autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL) {
+    password_manager_driver_->PreviewSuggestion(username, /*password=*/u"");
+    return true;
+  }
   autofill::PasswordAndMetadata password_and_meta_data;
   if (fill_data_ &&
       GetPasswordAndMetadataForUsername(username, item_id, *fill_data_,
diff --git a/components/password_manager/core/browser/password_autofill_manager.h b/components/password_manager/core/browser/password_autofill_manager.h
index 9b621c2..02e1954 100644
--- a/components/password_manager/core/browser/password_autofill_manager.h
+++ b/components/password_manager/core/browser/password_autofill_manager.h
@@ -126,6 +126,8 @@
   using ShowAllPasswords = base::StrongAlias<class ShowAllPasswordsTag, bool>;
   using ShowPasswordSuggestions =
       base::StrongAlias<class ShowPasswordSuggestionsTag, bool>;
+  using ShowWebAuthnCredentials =
+      base::StrongAlias<class ShowWebAuthnCredentialsTag, bool>;
 
   // Builds the suggestions used to show or update the autofill popup.
   std::vector<autofill::Suggestion> BuildSuggestions(
@@ -133,7 +135,8 @@
       ForPasswordField for_password_field,
       ShowAllPasswords show_all_passwords,
       OffersGeneration for_generation,
-      ShowPasswordSuggestions show_password_suggestions);
+      ShowPasswordSuggestions show_password_suggestions,
+      ShowWebAuthnCredentials show_webauthn_credentials);
 
   // Called just before showing a popup to log which |suggestions| were shown.
   void LogMetricsForSuggestions(
diff --git a/components/password_manager/core/browser/password_autofill_manager_unittest.cc b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
index a992485..a89b2ee 100644
--- a/components/password_manager/core/browser/password_autofill_manager_unittest.cc
+++ b/components/password_manager/core/browser/password_autofill_manager_unittest.cc
@@ -45,6 +45,7 @@
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/geometry/rect_f.h"
 #include "ui/gfx/image/image.h"
@@ -107,6 +108,19 @@
     "PasswordManager.CredentialsCountFromAccountStoreAfterUnlock";
 const gfx::Image kTestFavicon = gfx::test::CreateImage(16, 16);
 
+class MockWebAuthnCredentialsDelegate : public WebAuthnCredentialsDelegate {
+ public:
+  MOCK_METHOD(bool, IsWebAuthnAutofillEnabled, (), (const, override));
+  MOCK_METHOD(void,
+              SelectWebAuthnCredential,
+              (std::string backend_id),
+              (override));
+  MOCK_METHOD(std::vector<autofill::Suggestion>,
+              GetWebAuthnSuggestions,
+              (),
+              (const override));
+};
+
 class MockPasswordManagerDriver : public StubPasswordManagerDriver {
  public:
   MOCK_METHOD(void,
@@ -176,6 +190,10 @@
               NavigateToManagePasswordsPage,
               (ManagePasswordsReferrer),
               (override));
+  MOCK_METHOD(WebAuthnCredentialsDelegate*,
+              GetWebAuthnCredentialsDelegate,
+              (),
+              (override));
 
  private:
   MockPasswordManagerDriver driver_;
@@ -1761,4 +1779,62 @@
   password_autofill_manager_->OnAddPasswordFillData(CreateTestFormFillData());
 }
 
+TEST_F(PasswordAutofillManagerTest, ShowsWebAuthnSuggestions) {
+  TestPasswordManagerClient client;
+  NiceMock<MockAutofillClient> autofill_client;
+  MockWebAuthnCredentialsDelegate webauthn_credentials_delegate;
+  InitializePasswordAutofillManager(&client, &autofill_client);
+
+  // Return a WebAuthn credential.
+  const std::string kId = "abcd";
+  const std::u16string kName = u"nadeshiko@example.com";
+  const std::u16string kDisplayName = u"Nadeshiko Kagamihara";
+  autofill::Suggestion webauthn_credential(kDisplayName);
+  webauthn_credential.frontend_id = autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL;
+  webauthn_credential.backend_id = kId;
+  webauthn_credential.label = kName;
+  ON_CALL(webauthn_credentials_delegate, IsWebAuthnAutofillEnabled)
+      .WillByDefault(Return(true));
+  EXPECT_CALL(client, GetWebAuthnCredentialsDelegate)
+      .WillRepeatedly(Return(&webauthn_credentials_delegate));
+  EXPECT_CALL(webauthn_credentials_delegate, GetWebAuthnSuggestions)
+      .WillOnce(Return(std::vector<autofill::Suggestion>{webauthn_credential}));
+
+  // Show password suggestions including WebAuthn credentials.
+  autofill::AutofillClient::PopupOpenArgs open_args;
+  EXPECT_CALL(autofill_client, ShowAutofillPopup)
+      .WillOnce(testing::SaveArg<0>(&open_args));
+  gfx::RectF element_bounds;
+  password_autofill_manager_->OnShowPasswordSuggestions(
+      base::i18n::RIGHT_TO_LEFT, /*typed_username=*/std::u16string(),
+      autofill::ShowPasswordSuggestionsOptions::ACCEPTS_WEBAUTHN_CREDENTIALS,
+      element_bounds);
+  ASSERT_THAT(open_args.suggestions,
+              SuggestionVectorIdsAre(ElementsAre(
+                  autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL,
+                  autofill::POPUP_ITEM_ID_USERNAME_ENTRY,
+                  autofill::POPUP_ITEM_ID_ALL_SAVED_PASSWORDS_ENTRY)));
+  EXPECT_EQ(open_args.suggestions[0].backend_id, kId);
+  EXPECT_EQ(open_args.suggestions[0].frontend_id,
+            autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL);
+  EXPECT_EQ(open_args.suggestions[0].value, kDisplayName);
+  EXPECT_EQ(open_args.suggestions[0].label, kName);
+  testing::Mock::VerifyAndClearExpectations(client.mock_driver());
+
+  // Check that preview of the "username" (i.e. the credential name) works.
+  EXPECT_CALL(*client.mock_driver(),
+              PreviewSuggestion(kName, /*password=*/std::u16string(u"")));
+  password_autofill_manager_->DidSelectSuggestion(
+      kName, autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL);
+  testing::Mock::VerifyAndClearExpectations(client.mock_driver());
+
+  // Check that selecting the credential reports back to the client.
+  EXPECT_CALL(webauthn_credentials_delegate, SelectWebAuthnCredential(kId));
+  EXPECT_CALL(
+      autofill_client,
+      HideAutofillPopup(autofill::PopupHidingReason::kAcceptSuggestion));
+  password_autofill_manager_->DidAcceptSuggestion(
+      kName, autofill::POPUP_ITEM_ID_WEBAUTHN_CREDENTIAL, kId, /*position=*/1);
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_form_filling.cc b/components/password_manager/core/browser/password_form_filling.cc
index e7d0a712..4baa129 100644
--- a/components/password_manager/core/browser/password_form_filling.cc
+++ b/components/password_manager/core/browser/password_form_filling.cc
@@ -210,7 +210,8 @@
   } else if (IsFillOnAccountSelectFeatureEnabled()) {
     wait_for_username_reason = WaitForUsernameReason::kFoasFeature;
   } else if (observed_form.accepts_webauthn_credentials &&
-             client->IsWebAuthnAutofillEnabled()) {
+             client->GetWebAuthnCredentialsDelegate()
+                 ->IsWebAuthnAutofillEnabled()) {
     wait_for_username_reason =
         WaitForUsernameReason::kAcceptsWebAuthnCredentials;
   }
diff --git a/components/password_manager/core/browser/password_form_filling_unittest.cc b/components/password_manager/core/browser/password_form_filling_unittest.cc
index ab60770..1c3fe9b 100644
--- a/components/password_manager/core/browser/password_form_filling_unittest.cc
+++ b/components/password_manager/core/browser/password_form_filling_unittest.cc
@@ -21,6 +21,7 @@
 #include "components/password_manager/core/browser/password_form_metrics_recorder.h"
 #include "components/password_manager/core/browser/stub_password_manager_client.h"
 #include "components/password_manager/core/browser/stub_password_manager_driver.h"
+#include "components/password_manager/core/browser/webauthn_credentials_delegate.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -51,6 +52,19 @@
   MOCK_METHOD(void, InformNoSavedCredentials, (bool), (override));
 };
 
+class MockWebAuthnCredentialsDelegate : public WebAuthnCredentialsDelegate {
+ public:
+  MOCK_METHOD(bool, IsWebAuthnAutofillEnabled, (), (const, override));
+  MOCK_METHOD(void,
+              SelectWebAuthnCredential,
+              (std::string backend_id),
+              (override));
+  MOCK_METHOD(std::vector<autofill::Suggestion>,
+              GetWebAuthnSuggestions,
+              (),
+              (const override));
+};
+
 class MockPasswordManagerClient : public StubPasswordManagerClient {
  public:
   MOCK_METHOD(void,
@@ -64,7 +78,10 @@
               (const GURL&),
               (const, override));
   MOCK_METHOD(bool, IsCommittedMainFrameSecure, (), (const, override));
-  MOCK_METHOD(bool, IsWebAuthnAutofillEnabled, (), (const, override));
+  MOCK_METHOD(MockWebAuthnCredentialsDelegate*,
+              GetWebAuthnCredentialsDelegate,
+              (),
+              (override));
 };
 
 // Matcher for PasswordAndMetadata.
@@ -249,10 +266,13 @@
 
 #if !defined(ANDROID) && !defined(OS_IOS)
 TEST_F(PasswordFormFillingTest, DontFillOnLoadWebAuthnCredentials) {
+  MockWebAuthnCredentialsDelegate webauthn_credentials_delegate;
   observed_form_.accepts_webauthn_credentials = true;
   for (bool webauthn_autofill_enabled : {false, true}) {
     PasswordFormFillData fill_data;
-    EXPECT_CALL(client_, IsWebAuthnAutofillEnabled())
+    EXPECT_CALL(client_, GetWebAuthnCredentialsDelegate())
+        .WillOnce(Return(&webauthn_credentials_delegate));
+    EXPECT_CALL(webauthn_credentials_delegate, IsWebAuthnAutofillEnabled())
         .WillOnce(Return(webauthn_autofill_enabled));
     EXPECT_CALL(driver_, FillPasswordForm(_)).WillOnce(SaveArg<0>(&fill_data));
     EXPECT_CALL(client_, PasswordWasAutofilled);
diff --git a/components/password_manager/core/browser/password_manager_client.cc b/components/password_manager/core/browser/password_manager_client.cc
index 4d7be6b9..1ed6044 100644
--- a/components/password_manager/core/browser/password_manager_client.cc
+++ b/components/password_manager/core/browser/password_manager_client.cc
@@ -164,8 +164,8 @@
   return nullptr;
 }
 
-bool PasswordManagerClient::IsWebAuthnAutofillEnabled() const {
-  return false;
+WebAuthnCredentialsDelegate*
+PasswordManagerClient::GetWebAuthnCredentialsDelegate() {
+  return nullptr;
 }
-
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h
index b2cd474..99282f2 100644
--- a/components/password_manager/core/browser/password_manager_client.h
+++ b/components/password_manager/core/browser/password_manager_client.h
@@ -27,6 +27,7 @@
 #include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/browser/password_reuse_detector.h"
 #include "components/password_manager/core/browser/password_store.h"
+#include "components/password_manager/core/browser/webauthn_credentials_delegate.h"
 #include "components/profile_metrics/browser_profile_type.h"
 #include "components/safe_browsing/buildflags.h"
 #include "net/cert/cert_status_flags.h"
@@ -82,6 +83,7 @@
 class PasswordReuseManager;
 class PasswordStore;
 class PasswordStoreInterface;
+class WebAuthnCredentialsDelegate;
 struct PasswordForm;
 
 enum class SyncState {
@@ -379,6 +381,12 @@
       bool is_federated,
       const url::Origin& federated_origin) const {}
 
+  // If the feature is enabled send an event to the enterprise reporting
+  // connector server indicating that the user has some leaked credentials.
+  // |identities| contains the (url, username) pairs for each leaked identity.
+  virtual void MaybeReportEnterprisePasswordBreachEvent(
+      const std::vector<std::pair<GURL, std::u16string>>& identities) const {}
+
   // Gets a ukm::SourceId that is associated with the WebContents object
   // and its last committed main frame navigation.
   virtual ukm::SourceId GetUkmSourceId() = 0;
@@ -427,11 +435,11 @@
   // Returns a FieldInfoManager associated with the current profile.
   virtual FieldInfoManager* GetFieldInfoManager() const = 0;
 
-  // Returns true if integration between WebAuthn and Autofill is enabled.
-  virtual bool IsWebAuthnAutofillEnabled() const;
-
   // Returns if the Autofill Assistant UI is shown.
   virtual bool IsAutofillAssistantUIVisible() const = 0;
+
+  // Returns the WebAuthnCredentialsDelegate, if available.
+  virtual WebAuthnCredentialsDelegate* GetWebAuthnCredentialsDelegate();
 };
 
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h
index 82a20b5..4a870d15 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.h
+++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -390,7 +390,9 @@
   kUnlockAccountStoreGeneration = 4,
   // Previoulsy opted-in user decided to log-in again to access their passwords.
   kResigninToUnlockAccountStore = 5,
-  kMaxValue = kResigninToUnlockAccountStore
+  // User selected a WebAuthn credential.
+  kWebAuthn = 6,
+  kMaxValue = kWebAuthn
 };
 
 // These values are persisted to logs. Entries should not be renumbered and
diff --git a/components/password_manager/core/browser/webauthn_credentials_delegate.h b/components/password_manager/core/browser/webauthn_credentials_delegate.h
new file mode 100644
index 0000000..23aa024c
--- /dev/null
+++ b/components/password_manager/core/browser/webauthn_credentials_delegate.h
@@ -0,0 +1,35 @@
+// Copyright 2021 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_PASSWORD_MANAGER_CORE_BROWSER_WEBAUTHN_CREDENTIALS_DELEGATE_H_
+#define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_WEBAUTHN_CREDENTIALS_DELEGATE_H_
+
+#include <string>
+#include <vector>
+
+#include "components/autofill/core/browser/ui/suggestion.h"
+
+namespace password_manager {
+
+// Delegate facilitating communication between the password manager and
+// WebAuthn.
+class WebAuthnCredentialsDelegate {
+ public:
+  virtual ~WebAuthnCredentialsDelegate() = default;
+
+  // Returns true if integration between WebAuthn and Autofill is enabled.
+  virtual bool IsWebAuthnAutofillEnabled() const = 0;
+
+  // Called when the user selects a WebAuthn credential from the autofill
+  // suggestion list.
+  virtual void SelectWebAuthnCredential(std::string backend_id) = 0;
+
+  // Returns the list of eligible WebAuthn credentials to fulfill an ongoing
+  // WebAuthn request.
+  virtual std::vector<autofill::Suggestion> GetWebAuthnSuggestions() const = 0;
+};
+
+}  // namespace password_manager
+
+#endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_WEBAUTHN_CREDENTIALS_DELEGATE_H_
diff --git a/components/policy/core/common/features.cc b/components/policy/core/common/features.cc
index fc455b4e..b3a7a45 100644
--- a/components/policy/core/common/features.cc
+++ b/components/policy/core/common/features.cc
@@ -33,6 +33,9 @@
 const base::Feature kLoginEventReporting{"LoginEventReporting",
                                          base::FEATURE_DISABLED_BY_DEFAULT};
 
+const base::Feature kPasswordBreachEventReporting{
+    "PasswordBreachEventReporting", base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace features
 
 }  // namespace policy
diff --git a/components/policy/core/common/features.h b/components/policy/core/common/features.h
index d33dfea..45e93ed 100644
--- a/components/policy/core/common/features.h
+++ b/components/policy/core/common/features.h
@@ -37,8 +37,14 @@
 // Enable Chrome Remote Desktop for Managed Guest Sessions and affiliated users.
 POLICY_EXPORT extern const base::Feature kCRDForManagedUserSessions;
 
+// Enable reporting Login events to the reporting connector when the Password
+// Manager detects that the user logged in to a web page.
 POLICY_EXPORT extern const base::Feature kLoginEventReporting;
 
+// Enable reporting password leaks to the reporting connector when the Password
+// Manager's Leak Detector has found some compromised credentials.
+POLICY_EXPORT extern const base::Feature kPasswordBreachEventReporting;
+
 }  // namespace features
 }  // namespace policy
 
diff --git a/components/policy/resources/policy_templates.json b/components/policy/resources/policy_templates.json
index f220b71..0d9ffed8 100644
--- a/components/policy/resources/policy_templates.json
+++ b/components/policy/resources/policy_templates.json
@@ -10211,7 +10211,7 @@
       'owners': ['tylergarrett@google.com', 'cros-reporting-team@google.com'],
       'type': 'main',
       'schema': { 'type': 'boolean' },
-      'future_on': ['chrome_os'],
+      'supported_on': ['chrome_os:96-'],
       'supported_chrome_os_management': ['google_cloud'],
       'device_only': True,
       'features': {
@@ -10263,7 +10263,7 @@
       'owners': ['tylergarrett@google.com', 'cros-reporting-team@google.com'],
       'type': 'main',
       'schema': { 'type': 'boolean' },
-      'future_on': ['chrome_os'],
+      'supported_on': ['chrome_os:96-'],
       'supported_chrome_os_management': ['google_cloud'],
       'device_only': True,
       'features': {
diff --git a/components/reporting/client/report_queue_factory_unittest.cc b/components/reporting/client/report_queue_factory_unittest.cc
index a9d1978..168b7b5 100644
--- a/components/reporting/client/report_queue_factory_unittest.cc
+++ b/components/reporting/client/report_queue_factory_unittest.cc
@@ -89,7 +89,6 @@
 }
 
 // Tests if two consumers use the same provider and create two queues.
-// The test is flaky and has to be temporarily disabled. (crbug.com/1232156)
 TEST_F(ReportQueueFactoryTest, SameProviderForMultipleThreads) {
   const std::string dmToken2 = "TOKEN2";
   auto consumer2 = std::make_unique<MockReportQueueConsumer>();
diff --git a/components/reporting/client/report_queue_provider_unittest.cc b/components/reporting/client/report_queue_provider_unittest.cc
index 9cab930..d24a5b3 100644
--- a/components/reporting/client/report_queue_provider_unittest.cc
+++ b/components/reporting/client/report_queue_provider_unittest.cc
@@ -47,13 +47,7 @@
       base::BindRepeating([]() { return Status::StatusOK(); });
 };
 
-// Disable the test on Linux tsan due to flaky: crbug.com/1233804.
-#if defined(OS_LINUX) && defined(THREAD_SANITIZER)
-#define MAYBE_CreateAndGetQueue DISABLED_CreateAndGetQueue
-#else
-#define MAYBE_CreateAndGetQueue CreateAndGetQueue
-#endif
-TEST_F(ReportQueueProviderTest, MAYBE_CreateAndGetQueue) {
+TEST_F(ReportQueueProviderTest, CreateAndGetQueue) {
   std::unique_ptr<MockReportQueueProvider> provider =
       std::make_unique<NiceMock<MockReportQueueProvider>>();
   report_queue_provider_test_helper::SetForTesting(provider.get());
diff --git a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
index 0c6f4d38..72a2bac 100644
--- a/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
+++ b/components/safe_browsing/content/browser/safe_browsing_navigation_observer_manager.cc
@@ -93,11 +93,6 @@
 // metric "SafeBrowsing.NavigationObserver.NavigationEventCleanUpCount".
 // Lowering it could make room for abuse.
 static const int kNavigationRecordMaxSize = 100;
-// The maximum number ReferrerChainEntrys to add before truncating to
-// |kReferrerChainMaxLength|. It is used to limit memory usage when adding
-// entries to the ReferrerChain. This number is picked based on
-// |kNavigationRecordMaxSize|.
-static const int kReferrerChainRecordMaxSize = 100;
 // The maximum number of ReferrerChainEntry. It is used to limit the size of
 // reports (e.g. ClientDownloadRequest) we send to SB server.
 static const int kReferrerChainMaxLength = 10;
@@ -846,8 +841,7 @@
       safe_browsing::kOmitNonUserGesturesFromReferrerChain);
 
   GURL last_main_frame_url_traced(last_nav_event_traced->source_main_frame_url);
-  while (current_user_gesture_count < user_gesture_count_limit &&
-         (out_referrer_chain->size() < kReferrerChainRecordMaxSize)) {
+  while (current_user_gesture_count < user_gesture_count_limit) {
     // Back trace to the next nav_event that was initiated by the user.
     while (!last_nav_event_traced->IsUserInitiated()) {
       last_nav_event_traced_index = navigation_event_list_.FindNavigationEvent(
diff --git a/components/services/app_service/public/cpp/intent_filter_util.cc b/components/services/app_service/public/cpp/intent_filter_util.cc
index 9f86b5b..d9a76d4 100644
--- a/components/services/app_service/public/cpp/intent_filter_util.cc
+++ b/components/services/app_service/public/cpp/intent_filter_util.cc
@@ -232,27 +232,45 @@
 }
 
 bool IsSupportedLink(const apps::mojom::IntentFilterPtr& intent_filter) {
+  bool action = false;
   bool scheme = false;
   bool host = false;
+  bool pattern = false;
   for (auto& condition : intent_filter->conditions) {
-    if (condition->condition_type == apps::mojom::ConditionType::kScheme) {
-      for (auto& condition_value : condition->condition_values) {
-        if (condition_value->value == "http" ||
-            condition_value->value == "https") {
-          scheme = true;
-          break;
+    switch (condition->condition_type) {
+      case apps::mojom::ConditionType::kAction:
+        for (auto& condition_value : condition->condition_values) {
+          if (condition_value->value == apps_util::kIntentActionView) {
+            action = true;
+            break;
+          }
         }
-      }
-    } else if (condition->condition_type == apps::mojom::ConditionType::kHost) {
-      host = true;
+        break;
+      case apps::mojom::ConditionType::kScheme:
+        for (auto& condition_value : condition->condition_values) {
+          if (condition_value->value == "http" ||
+              condition_value->value == "https") {
+            scheme = true;
+            break;
+          }
+        }
+        break;
+      case apps::mojom::ConditionType::kHost:
+        host = true;
+        break;
+      case apps::mojom::ConditionType::kPattern:
+        pattern = true;
+        break;
+      default:
+        break;
     }
 
-    if (scheme && host) {
-      break;
+    if (action && scheme && host && pattern) {
+      return true;
     }
   }
 
-  return scheme && host;
+  return false;
 }
 
 }  // namespace apps_util
diff --git a/components/services/app_service/public/cpp/intent_filter_util.h b/components/services/app_service/public/cpp/intent_filter_util.h
index fc1f25a..d53efee0 100644
--- a/components/services/app_service/public/cpp/intent_filter_util.h
+++ b/components/services/app_service/public/cpp/intent_filter_util.h
@@ -89,8 +89,8 @@
 std::set<std::string> AppManagementGetSupportedLinks(
     const apps::mojom::IntentFilterPtr& intent_filter);
 
-// Check if the filter is a supported link, i.e. it has a http or https scheme
-// and at least one host.
+// Check if the filter is a supported link, i.e. it has the "view" action, a
+// http or https scheme, and at least one host and pattern.
 bool IsSupportedLink(const apps::mojom::IntentFilterPtr& intent_filter);
 
 }  // namespace apps_util
diff --git a/components/services/app_service/public/cpp/intent_filter_util_unittest.cc b/components/services/app_service/public/cpp/intent_filter_util_unittest.cc
index ea9ac579..801e75b 100644
--- a/components/services/app_service/public/cpp/intent_filter_util_unittest.cc
+++ b/components/services/app_service/public/cpp/intent_filter_util_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "base/values.h"
 #include "components/services/app_service/public/cpp/intent_test_util.h"
+#include "components/services/app_service/public/cpp/intent_util.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -32,6 +33,10 @@
     auto intent_filter = apps::mojom::IntentFilter::New();
 
     apps_util::AddSingleValueCondition(
+        apps::mojom::ConditionType::kAction, apps_util::kIntentActionView,
+        apps::mojom::PatternMatchType::kNone, intent_filter);
+
+    apps_util::AddSingleValueCondition(
         apps::mojom::ConditionType::kScheme, scheme,
         apps::mojom::PatternMatchType::kNone, intent_filter);
 
@@ -218,3 +223,39 @@
   EXPECT_EQ(links.size(), 1u);
   EXPECT_EQ(links.count(kUrlGoogleLiteral), 1u);
 }
+
+TEST_F(IntentFilterUtilTest, IsSupportedLink) {
+  auto filter = MakeFilter("https", "www.google.com", "/maps",
+                           apps::mojom::PatternMatchType::kLiteral);
+  ASSERT_TRUE(apps_util::IsSupportedLink(filter));
+
+  filter = MakeFilter("https", "www.google.com", ".*",
+                      apps::mojom::PatternMatchType::kGlob);
+  ASSERT_TRUE(apps_util::IsSupportedLink(filter));
+}
+
+TEST_F(IntentFilterUtilTest, NotSupportedLink) {
+  ASSERT_FALSE(apps_util::IsSupportedLink(
+      apps_util::CreateIntentFilterForMimeType("image/png")));
+
+  auto browser_filter = apps::mojom::IntentFilter::New();
+  apps_util::AddSingleValueCondition(
+      apps::mojom::ConditionType::kAction, apps_util::kIntentActionView,
+      apps::mojom::PatternMatchType::kNone, browser_filter);
+  apps_util::AddSingleValueCondition(
+      apps::mojom::ConditionType::kScheme, "https",
+      apps::mojom::PatternMatchType::kNone, browser_filter);
+  ASSERT_FALSE(apps_util::IsSupportedLink(browser_filter));
+
+  auto host_filter = apps::mojom::IntentFilter::New();
+  apps_util::AddSingleValueCondition(
+      apps::mojom::ConditionType::kAction, apps_util::kIntentActionView,
+      apps::mojom::PatternMatchType::kNone, host_filter);
+  apps_util::AddSingleValueCondition(
+      apps::mojom::ConditionType::kScheme, "https",
+      apps::mojom::PatternMatchType::kNone, host_filter);
+  apps_util::AddSingleValueCondition(
+      apps::mojom::ConditionType::kHost, "www.example.com",
+      apps::mojom::PatternMatchType::kNone, host_filter);
+  ASSERT_FALSE(apps_util::IsSupportedLink(browser_filter));
+}
diff --git a/components/sync/base/extensions_activity.cc b/components/sync/base/extensions_activity.cc
index 235ea14f..e2f88c4 100644
--- a/components/sync/base/extensions_activity.cc
+++ b/components/sync/base/extensions_activity.cc
@@ -8,11 +8,11 @@
 
 ExtensionsActivity::Record::Record() : bookmark_write_count(0U) {}
 
-ExtensionsActivity::Record::~Record() {}
+ExtensionsActivity::Record::~Record() = default;
 
-ExtensionsActivity::ExtensionsActivity() {}
+ExtensionsActivity::ExtensionsActivity() = default;
 
-ExtensionsActivity::~ExtensionsActivity() {}
+ExtensionsActivity::~ExtensionsActivity() = default;
 
 void ExtensionsActivity::GetAndClearRecords(Records* buffer) {
   base::AutoLock lock(records_lock_);
@@ -22,9 +22,11 @@
 
 void ExtensionsActivity::PutRecords(const Records& records) {
   base::AutoLock lock(records_lock_);
-  for (auto i = records.begin(); i != records.end(); ++i) {
-    records_[i->first].extension_id = i->second.extension_id;
-    records_[i->first].bookmark_write_count += i->second.bookmark_write_count;
+  for (const auto& id_and_record : records) {
+    const std::string& id = id_and_record.first;
+    const Record& record = id_and_record.second;
+    records_[id].extension_id = record.extension_id;
+    records_[id].bookmark_write_count += record.bookmark_write_count;
   }
 }
 
diff --git a/components/sync/base/invalidation_interface.cc b/components/sync/base/invalidation_interface.cc
index ec7555e..67f5876 100644
--- a/components/sync/base/invalidation_interface.cc
+++ b/components/sync/base/invalidation_interface.cc
@@ -20,8 +20,8 @@
   return a.GetVersion() < b.GetVersion();
 }
 
-InvalidationInterface::InvalidationInterface() {}
+InvalidationInterface::InvalidationInterface() = default;
 
-InvalidationInterface::~InvalidationInterface() {}
+InvalidationInterface::~InvalidationInterface() = default;
 
 }  // namespace syncer
diff --git a/components/sync/base/model_type_test_util.cc b/components/sync/base/model_type_test_util.cc
index 8378b290..a0848670 100644
--- a/components/sync/base/model_type_test_util.cc
+++ b/components/sync/base/model_type_test_util.cc
@@ -20,19 +20,20 @@
   explicit HasModelTypesMatcher(ModelTypeSet expected_types)
       : expected_types_(expected_types) {}
 
-  virtual ~HasModelTypesMatcher() {}
+  ~HasModelTypesMatcher() override = default;
 
-  virtual bool MatchAndExplain(ModelTypeSet model_types,
-                               ::testing::MatchResultListener* listener) const {
+  bool MatchAndExplain(
+      ModelTypeSet model_types,
+      ::testing::MatchResultListener* listener) const override {
     // No need to annotate listener since we already define PrintTo().
     return model_types == expected_types_;
   }
 
-  virtual void DescribeTo(::std::ostream* os) const {
+  void DescribeTo(::std::ostream* os) const override {
     *os << "has model types " << ModelTypeSetToString(expected_types_);
   }
 
-  virtual void DescribeNegationTo(::std::ostream* os) const {
+  void DescribeNegationTo(::std::ostream* os) const override {
     *os << "doesn't have model types " << ModelTypeSetToString(expected_types_);
   }
 
diff --git a/components/sync/base/ordinal_unittest.cc b/components/sync/base/ordinal_unittest.cc
index fb2f51c..3ad7b661 100644
--- a/components/sync/base/ordinal_unittest.cc
+++ b/components/sync/base/ordinal_unittest.cc
@@ -202,8 +202,8 @@
 bool IsNonEmptyPrintableString(const std::string& str) {
   if (str.empty())
     return false;
-  for (size_t i = 0; i < str.length(); ++i) {
-    if (!isprint(str[i]))
+  for (char c : str) {
+    if (!isprint(c))
       return false;
   }
   return true;
diff --git a/components/sync/base/progress_marker_map.cc b/components/sync/base/progress_marker_map.cc
index c664a90f..e2d9c58b2d 100644
--- a/components/sync/base/progress_marker_map.cc
+++ b/components/sync/base/progress_marker_map.cc
@@ -14,12 +14,13 @@
 std::unique_ptr<base::DictionaryValue> ProgressMarkerMapToValue(
     const ProgressMarkerMap& marker_map) {
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
-  for (auto it = marker_map.begin(); it != marker_map.end(); ++it) {
+  for (const auto& model_type_and_progress_marker : marker_map) {
     std::string printable_payload;
-    base::EscapeJSONString(it->second, false /* put_in_quotes */,
-                           &printable_payload);
+    base::EscapeJSONString(model_type_and_progress_marker.second,
+                           false /* put_in_quotes */, &printable_payload);
     base::Base64Encode(printable_payload, &printable_payload);
-    value->SetString(ModelTypeToString(it->first), printable_payload);
+    value->SetString(ModelTypeToString(model_type_and_progress_marker.first),
+                     printable_payload);
   }
   return value;
 }
diff --git a/components/sync/base/sync_prefs.cc b/components/sync/base/sync_prefs.cc
index 1074ebf..fb2c460 100644
--- a/components/sync/base/sync_prefs.cc
+++ b/components/sync/base/sync_prefs.cc
@@ -37,7 +37,7 @@
 
 }  // namespace
 
-SyncPrefObserver::~SyncPrefObserver() {}
+SyncPrefObserver::~SyncPrefObserver() = default;
 
 SyncPrefs::SyncPrefs(PrefService* pref_service) : pref_service_(pref_service) {
   DCHECK(pref_service);
diff --git a/components/sync/base/unique_position.cc b/components/sync/base/unique_position.cc
index d732c27..5ce5336 100644
--- a/components/sync/base/unique_position.cc
+++ b/components/sync/base/unique_position.cc
@@ -475,9 +475,10 @@
   DCHECK_LE(i + 4, str.length());
 
   // Step 1: Extract the big-endian count.
-  uint32_t encoded_length =
-      ((uint8_t)(str[i + 3]) << 0) | ((uint8_t)(str[i + 2]) << 8) |
-      ((uint8_t)(str[i + 1]) << 16) | ((uint8_t)(str[i + 0]) << 24);
+  uint32_t encoded_length = (static_cast<uint8_t>(str[i + 3]) << 0) |
+                            (static_cast<uint8_t>(str[i + 2]) << 8) |
+                            (static_cast<uint8_t>(str[i + 1]) << 16) |
+                            (static_cast<uint8_t>(str[i + 0]) << 24);
 
   // Step 2: If this was an inverted count, un-invert it.
   uint32_t length;
diff --git a/components/sync/base/weak_handle.cc b/components/sync/base/weak_handle.cc
index e30b4eb..b9dbc5b18 100644
--- a/components/sync/base/weak_handle.cc
+++ b/components/sync/base/weak_handle.cc
@@ -21,7 +21,7 @@
   return owner_loop_task_runner_->RunsTasksInCurrentSequence();
 }
 
-WeakHandleCoreBase::~WeakHandleCoreBase() {}
+WeakHandleCoreBase::~WeakHandleCoreBase() = default;
 
 void WeakHandleCoreBase::PostToOwnerThread(const base::Location& from_here,
                                            base::OnceClosure fn) const {
diff --git a/components/sync/base/weak_handle_unittest.cc b/components/sync/base/weak_handle_unittest.cc
index daad6abf..1618d5e 100644
--- a/components/sync/base/weak_handle_unittest.cc
+++ b/components/sync/base/weak_handle_unittest.cc
@@ -19,7 +19,7 @@
 
 class Base {
  public:
-  Base() {}
+  Base() = default;
 
   WeakHandle<Base> AsWeakHandle() {
     return MakeWeakHandle(weak_ptr_factory_.GetWeakPtr());
diff --git a/components/sync/driver/backend_migrator.cc b/components/sync/driver/backend_migrator.cc
index 5809f5a..0164109 100644
--- a/components/sync/driver/backend_migrator.cc
+++ b/components/sync/driver/backend_migrator.cc
@@ -13,7 +13,7 @@
 
 namespace syncer {
 
-MigrationObserver::~MigrationObserver() {}
+MigrationObserver::~MigrationObserver() = default;
 
 BackendMigrator::BackendMigrator(
     const std::string& name,
@@ -29,7 +29,7 @@
   DCHECK(!migration_done_callback_.is_null());
 }
 
-BackendMigrator::~BackendMigrator() {}
+BackendMigrator::~BackendMigrator() = default;
 
 // Helper macros to log with the syncer thread name; useful when there
 // are multiple syncer threads involved.
diff --git a/components/sync/driver/backend_migrator_unittest.cc b/components/sync/driver/backend_migrator_unittest.cc
index 07ce390..eee980f 100644
--- a/components/sync/driver/backend_migrator_unittest.cc
+++ b/components/sync/driver/backend_migrator_unittest.cc
@@ -24,8 +24,8 @@
 
 class SyncBackendMigratorTest : public testing::Test {
  public:
-  SyncBackendMigratorTest() {}
-  ~SyncBackendMigratorTest() override {}
+  SyncBackendMigratorTest() = default;
+  ~SyncBackendMigratorTest() override = default;
 
   void SetUp() override {
     Mock::VerifyAndClear(manager());
@@ -82,7 +82,7 @@
 
 class MockMigrationObserver : public MigrationObserver {
  public:
-  ~MockMigrationObserver() override {}
+  ~MockMigrationObserver() override = default;
 
   MOCK_METHOD(void, OnMigrationStateChange, ());
 };
diff --git a/components/sync/driver/data_type_controller.cc b/components/sync/driver/data_type_controller.cc
index c1c582b5..aa619827 100644
--- a/components/sync/driver/data_type_controller.cc
+++ b/components/sync/driver/data_type_controller.cc
@@ -8,7 +8,7 @@
 
 DataTypeController::DataTypeController(ModelType type) : type_(type) {}
 
-DataTypeController::~DataTypeController() {}
+DataTypeController::~DataTypeController() = default;
 
 // static
 std::string DataTypeController::StateToString(State state) {
diff --git a/components/sync/driver/data_type_manager.cc b/components/sync/driver/data_type_manager.cc
index d89a697..a002e65 100644
--- a/components/sync/driver/data_type_manager.cc
+++ b/components/sync/driver/data_type_manager.cc
@@ -15,7 +15,7 @@
 DataTypeManager::ConfigureResult::ConfigureResult(
     const ConfigureResult& other) = default;
 
-DataTypeManager::ConfigureResult::~ConfigureResult() {}
+DataTypeManager::ConfigureResult::~ConfigureResult() = default;
 
 // Static.
 std::string DataTypeManager::ConfigureStatusToString(ConfigureStatus status) {
diff --git a/components/sync/driver/data_type_manager_mock.cc b/components/sync/driver/data_type_manager_mock.cc
index d972780..1c9531c 100644
--- a/components/sync/driver/data_type_manager_mock.cc
+++ b/components/sync/driver/data_type_manager_mock.cc
@@ -10,6 +10,6 @@
 
 DataTypeManagerMock::DataTypeManagerMock() : result_(OK, ModelTypeSet()) {}
 
-DataTypeManagerMock::~DataTypeManagerMock() {}
+DataTypeManagerMock::~DataTypeManagerMock() = default;
 
 }  // namespace syncer
diff --git a/components/sync/driver/data_type_status_table.cc b/components/sync/driver/data_type_status_table.cc
index 8762d97..b1d5d2e 100644
--- a/components/sync/driver/data_type_status_table.cc
+++ b/components/sync/driver/data_type_status_table.cc
@@ -23,18 +23,19 @@
 
 }  // namespace
 
-DataTypeStatusTable::DataTypeStatusTable() {}
+DataTypeStatusTable::DataTypeStatusTable() = default;
 
 DataTypeStatusTable::DataTypeStatusTable(const DataTypeStatusTable& other) =
     default;
 
-DataTypeStatusTable::~DataTypeStatusTable() {}
+DataTypeStatusTable::~DataTypeStatusTable() = default;
 
 void DataTypeStatusTable::UpdateFailedDataTypes(const TypeErrorMap& errors) {
   DVLOG(1) << "Setting " << errors.size() << " new failed types.";
 
-  for (auto iter = errors.begin(); iter != errors.end(); ++iter) {
-    UpdateFailedDataType(iter->first, iter->second);
+  for (const auto& model_type_and_error : errors) {
+    UpdateFailedDataType(model_type_and_error.first,
+                         model_type_and_error.second);
   }
 }
 
diff --git a/components/sync/driver/fake_data_type_controller.cc b/components/sync/driver/fake_data_type_controller.cc
index 85c287f..7a944094 100644
--- a/components/sync/driver/fake_data_type_controller.cc
+++ b/components/sync/driver/fake_data_type_controller.cc
@@ -24,7 +24,7 @@
               ? std::make_unique<FakeModelTypeControllerDelegate>(type)
               : nullptr) {}
 
-FakeDataTypeController::~FakeDataTypeController() {}
+FakeDataTypeController::~FakeDataTypeController() = default;
 
 void FakeDataTypeController::SetPreconditionState(PreconditionState state) {
   precondition_state_ = state;
diff --git a/components/sync/driver/model_type_controller_unittest.cc b/components/sync/driver/model_type_controller_unittest.cc
index 7cb9a251..cce1d943 100644
--- a/components/sync/driver/model_type_controller_unittest.cc
+++ b/components/sync/driver/model_type_controller_unittest.cc
@@ -74,7 +74,7 @@
       std::unique_ptr<ModelTypeControllerDelegate> delegate_for_full_sync_mode)
       : ModelTypeController(kTestModelType,
                             std::move(delegate_for_full_sync_mode)) {}
-  ~TestModelTypeController() override {}
+  ~TestModelTypeController() override = default;
 
   using ModelTypeController::ReportModelError;
 };
@@ -94,7 +94,7 @@
       : controller_(std::make_unique<ForwardingModelTypeControllerDelegate>(
             &mock_delegate_)) {}
 
-  ~ModelTypeControllerTest() {}
+  ~ModelTypeControllerTest() override = default;
 
   bool LoadModels(bool initial_sync_done = false) {
     base::MockCallback<DataTypeController::ModelLoadCallback> load_models_done;
diff --git a/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc b/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc
index 84b7234..b36b883 100644
--- a/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc
+++ b/components/sync/driver/non_ui_syncable_service_based_model_type_controller.cc
@@ -159,6 +159,6 @@
 }
 
 NonUiSyncableServiceBasedModelTypeController::
-    ~NonUiSyncableServiceBasedModelTypeController() {}
+    ~NonUiSyncableServiceBasedModelTypeController() = default;
 
 }  // namespace syncer
diff --git a/components/sync/driver/sync_auth_manager_unittest.cc b/components/sync/driver/sync_auth_manager_unittest.cc
index e79b5d4..a840948 100644
--- a/components/sync/driver/sync_auth_manager_unittest.cc
+++ b/components/sync/driver/sync_auth_manager_unittest.cc
@@ -34,7 +34,7 @@
 
   SyncAuthManagerTest() : identity_env_(&test_url_loader_factory_) {}
 
-  ~SyncAuthManagerTest() override {}
+  ~SyncAuthManagerTest() override = default;
 
   std::unique_ptr<SyncAuthManager> CreateAuthManager() {
     return CreateAuthManager(base::DoNothing(), base::DoNothing());
diff --git a/components/sync/driver/sync_service_impl_bundle.cc b/components/sync/driver/sync_service_impl_bundle.cc
index 9596275c..1a61aae 100644
--- a/components/sync/driver/sync_service_impl_bundle.cc
+++ b/components/sync/driver/sync_service_impl_bundle.cc
@@ -26,7 +26,7 @@
   identity_test_env_.SetAutomaticIssueOfAccessTokens(true);
 }
 
-SyncServiceImplBundle::~SyncServiceImplBundle() {}
+SyncServiceImplBundle::~SyncServiceImplBundle() = default;
 
 std::unique_ptr<SyncClientMock> SyncServiceImplBundle::CreateSyncClientMock() {
   auto sync_client = std::make_unique<testing::NiceMock<SyncClientMock>>();
diff --git a/components/sync/driver/sync_service_impl_unittest.cc b/components/sync/driver/sync_service_impl_unittest.cc
index b70c997..849bbcf 100644
--- a/components/sync/driver/sync_service_impl_unittest.cc
+++ b/components/sync/driver/sync_service_impl_unittest.cc
@@ -62,8 +62,7 @@
 
 class TestSyncServiceObserver : public SyncServiceObserver {
  public:
-  TestSyncServiceObserver()
-      : setup_in_progress_(false), auth_error_(GoogleServiceAuthError()) {}
+  TestSyncServiceObserver() = default;
 
   void OnStateChanged(SyncService* sync) override {
     setup_in_progress_ = sync->IsSetupInProgress();
@@ -74,7 +73,7 @@
   GoogleServiceAuthError auth_error() const { return auth_error_; }
 
  private:
-  bool setup_in_progress_;
+  bool setup_in_progress_ = false;
   GoogleServiceAuthError auth_error_;
 };
 
@@ -85,8 +84,8 @@
 // testing the SyncEngine.
 class SyncServiceImplTest : public ::testing::Test {
  protected:
-  SyncServiceImplTest() {}
-  ~SyncServiceImplTest() override {}
+  SyncServiceImplTest() = default;
+  ~SyncServiceImplTest() override = default;
 
   void SetUp() override {
     base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
diff --git a/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc b/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc
index 68d170a..b74f280 100644
--- a/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc
+++ b/components/sync/driver/sync_session_durations_metrics_recorder_unittest.cc
@@ -29,7 +29,7 @@
     sync_service_.SetDisableReasons(SyncService::DISABLE_REASON_NOT_SIGNED_IN);
   }
 
-  ~SyncSessionDurationsMetricsRecorderTest() override {}
+  ~SyncSessionDurationsMetricsRecorderTest() override = default;
 
   void EnableSync() {
     identity_test_env_.MakePrimaryAccountAvailable("foo@gmail.com",
diff --git a/components/sync/driver/sync_stopped_reporter.cc b/components/sync/driver/sync_stopped_reporter.cc
index 0ea6ade..3571eee 100644
--- a/components/sync/driver/sync_stopped_reporter.cc
+++ b/components/sync/driver/sync_stopped_reporter.cc
@@ -48,7 +48,7 @@
   DCHECK(url_loader_factory_);
 }
 
-SyncStoppedReporter::~SyncStoppedReporter() {}
+SyncStoppedReporter::~SyncStoppedReporter() = default;
 
 void SyncStoppedReporter::ReportSyncStopped(const std::string& access_token,
                                             const std::string& cache_guid,
diff --git a/components/sync/driver/sync_stopped_reporter_unittest.cc b/components/sync/driver/sync_stopped_reporter_unittest.cc
index ebe26a94..0ef2b2b5 100644
--- a/components/sync/driver/sync_stopped_reporter_unittest.cc
+++ b/components/sync/driver/sync_stopped_reporter_unittest.cc
@@ -34,8 +34,8 @@
 
 class SyncStoppedReporterTest : public testing::Test {
  protected:
-  SyncStoppedReporterTest() {}
-  ~SyncStoppedReporterTest() override {}
+  SyncStoppedReporterTest() = default;
+  ~SyncStoppedReporterTest() override = default;
 
   void SetUp() override {
     test_shared_loader_factory_ =
diff --git a/components/sync/driver/syncable_service_based_model_type_controller.cc b/components/sync/driver/syncable_service_based_model_type_controller.cc
index d72f319..5256cf0 100644
--- a/components/sync/driver/syncable_service_based_model_type_controller.cc
+++ b/components/sync/driver/syncable_service_based_model_type_controller.cc
@@ -36,7 +36,7 @@
     }
   }
 
-  ~ControllerDelegate() override {}
+  ~ControllerDelegate() override = default;
 
   void OnSyncStarting(const DataTypeActivationRequest& request,
                       StartCallback callback) override {
diff --git a/components/sync/engine/backoff_delay_provider.cc b/components/sync/engine/backoff_delay_provider.cc
index 4dd389a..5a32d05 100644
--- a/components/sync/engine/backoff_delay_provider.cc
+++ b/components/sync/engine/backoff_delay_provider.cc
@@ -60,7 +60,7 @@
     : default_initial_backoff_(default_initial_backoff),
       short_initial_backoff_(short_initial_backoff) {}
 
-BackoffDelayProvider::~BackoffDelayProvider() {}
+BackoffDelayProvider::~BackoffDelayProvider() = default;
 
 base::TimeDelta BackoffDelayProvider::GetDelay(
     const base::TimeDelta& last_delay) {
diff --git a/components/sync/engine/cancelation_signal_unittest.cc b/components/sync/engine/cancelation_signal_unittest.cc
index 74bf66d..3849656 100644
--- a/components/sync/engine/cancelation_signal_unittest.cc
+++ b/components/sync/engine/cancelation_signal_unittest.cc
@@ -123,7 +123,7 @@
                        base::WaitableEvent::InitialState::NOT_SIGNALED),
       blocking_task_(&signal_) {}
 
-CancelationSignalTest::~CancelationSignalTest() {}
+CancelationSignalTest::~CancelationSignalTest() = default;
 
 void CancelationSignalTest::StartBlockingTaskAsync() {
   blocking_task_.RunAsync(&task_start_event_, &task_done_event_);
diff --git a/components/sync/engine/commit_processor.cc b/components/sync/engine/commit_processor.cc
index aa4f559..2a46d6f 100644
--- a/components/sync/engine/commit_processor.cc
+++ b/components/sync/engine/commit_processor.cc
@@ -28,7 +28,7 @@
   DCHECK(commit_contributor_map);
 }
 
-CommitProcessor::~CommitProcessor() {}
+CommitProcessor::~CommitProcessor() = default;
 
 Commit::ContributionMap CommitProcessor::GatherCommitContributions(
     size_t max_entries) {
diff --git a/components/sync/engine/commit_util.cc b/components/sync/engine/commit_util.cc
index 751c1b5..394000a6 100644
--- a/components/sync/engine/commit_util.cc
+++ b/components/sync/engine/commit_util.cc
@@ -25,12 +25,12 @@
   activity->GetAndClearRecords(extensions_activity_buffer);
 
   const ExtensionsActivity::Records& records = *extensions_activity_buffer;
-  for (auto it = records.begin(); it != records.end(); ++it) {
+  for (const auto& id_and_record : records) {
     sync_pb::ChromiumExtensionsActivity* activity_message =
         message->add_extensions_activity();
-    activity_message->set_extension_id(it->second.extension_id);
+    activity_message->set_extension_id(id_and_record.second.extension_id);
     activity_message->set_bookmark_writes_since_last_commit(
-        it->second.bookmark_write_count);
+        id_and_record.second.bookmark_write_count);
   }
 }
 
diff --git a/components/sync/engine/cycle/data_type_tracker.cc b/components/sync/engine/cycle/data_type_tracker.cc
index 87d95bd0..c6a7309 100644
--- a/components/sync/engine/cycle/data_type_tracker.cc
+++ b/components/sync/engine/cycle/data_type_tracker.cc
@@ -202,9 +202,9 @@
   // crash before writing all our state, we should wait until the results of
   // this sync cycle have been written to disk before updating the invalidations
   // state.  See crbug.com/324996.
-  for (auto it = pending_invalidations_.begin();
-       it != pending_invalidations_.end(); ++it) {
-    (*it)->Acknowledge();
+  for (const std::unique_ptr<InvalidationInterface>& pending_invalidation :
+       pending_invalidations_) {
+    pending_invalidation->Acknowledge();
   }
   pending_invalidations_.clear();
 
@@ -295,10 +295,10 @@
   // Fill the list of payloads, if applicable.  The payloads must be ordered
   // oldest to newest, so we insert them in the same order as we've been storing
   // them internally.
-  for (auto it = pending_invalidations_.begin();
-       it != pending_invalidations_.end(); ++it) {
-    if (!(*it)->IsUnknownVersion()) {
-      msg->add_notification_hint((*it)->GetPayload());
+  for (const std::unique_ptr<InvalidationInterface>& pending_invalidation :
+       pending_invalidations_) {
+    if (!pending_invalidation->IsUnknownVersion()) {
+      msg->add_notification_hint(pending_invalidation->GetPayload());
     }
   }
 
diff --git a/components/sync/engine/cycle/mock_debug_info_getter.cc b/components/sync/engine/cycle/mock_debug_info_getter.cc
index cb611e4..d40b869 100644
--- a/components/sync/engine/cycle/mock_debug_info_getter.cc
+++ b/components/sync/engine/cycle/mock_debug_info_getter.cc
@@ -6,9 +6,9 @@
 
 namespace syncer {
 
-MockDebugInfoGetter::MockDebugInfoGetter() {}
+MockDebugInfoGetter::MockDebugInfoGetter() = default;
 
-MockDebugInfoGetter::~MockDebugInfoGetter() {}
+MockDebugInfoGetter::~MockDebugInfoGetter() = default;
 
 sync_pb::DebugInfo MockDebugInfoGetter::GetDebugInfo() const {
   return debug_info_;
diff --git a/components/sync/engine/cycle/model_neutral_state.cc b/components/sync/engine/cycle/model_neutral_state.cc
index 7f63e1a..5eb87aa 100644
--- a/components/sync/engine/cycle/model_neutral_state.cc
+++ b/components/sync/engine/cycle/model_neutral_state.cc
@@ -22,7 +22,7 @@
 
 ModelNeutralState::ModelNeutralState(const ModelNeutralState& other) = default;
 
-ModelNeutralState::~ModelNeutralState() {}
+ModelNeutralState::~ModelNeutralState() = default;
 
 bool HasSyncerError(const ModelNeutralState& state) {
   const bool get_key_error = state.last_get_key_result.IsActualError();
diff --git a/components/sync/engine/cycle/nudge_tracker_unittest.cc b/components/sync/engine/cycle/nudge_tracker_unittest.cc
index 2ed68f49..47610c2 100644
--- a/components/sync/engine/cycle/nudge_tracker_unittest.cc
+++ b/components/sync/engine/cycle/nudge_tracker_unittest.cc
@@ -866,7 +866,7 @@
 
 class NudgeTrackerAckTrackingTest : public NudgeTrackerTest {
  public:
-  NudgeTrackerAckTrackingTest() {}
+  NudgeTrackerAckTrackingTest() = default;
 
   bool IsInvalidationUnacknowledged(int tracking_id) {
     return tracker_.IsUnacked(tracking_id);
diff --git a/components/sync/engine/cycle/status_controller.cc b/components/sync/engine/cycle/status_controller.cc
index 16eb070..1d2498f 100644
--- a/components/sync/engine/cycle/status_controller.cc
+++ b/components/sync/engine/cycle/status_controller.cc
@@ -9,9 +9,9 @@
 
 namespace syncer {
 
-StatusController::StatusController() {}
+StatusController::StatusController() = default;
 
-StatusController::~StatusController() {}
+StatusController::~StatusController() = default;
 
 const ModelTypeSet StatusController::get_updates_request_types() const {
   return model_neutral_.get_updates_request_types;
diff --git a/components/sync/engine/cycle/sync_cycle.cc b/components/sync/engine/cycle/sync_cycle.cc
index 532d22e..216986f 100644
--- a/components/sync/engine/cycle/sync_cycle.cc
+++ b/components/sync/engine/cycle/sync_cycle.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 #include <iterator>
+#include <vector>
 
 #include "base/logging.h"
 #include "components/sync/engine/update_handler.h"
@@ -17,7 +18,7 @@
   status_controller_ = std::make_unique<StatusController>();
 }
 
-SyncCycle::~SyncCycle() {}
+SyncCycle::~SyncCycle() = default;
 
 SyncCycleSnapshot SyncCycle::TakeSnapshot() const {
   return TakeSnapshotWithOrigin(sync_pb::SyncEnums::UNKNOWN_ORIGIN);
diff --git a/components/sync/engine/cycle/sync_cycle_snapshot.cc b/components/sync/engine/cycle/sync_cycle_snapshot.cc
index d7bcb40f..f2d4d4eb 100644
--- a/components/sync/engine/cycle/sync_cycle_snapshot.cc
+++ b/components/sync/engine/cycle/sync_cycle_snapshot.cc
@@ -78,7 +78,7 @@
 
 SyncCycleSnapshot::SyncCycleSnapshot(const SyncCycleSnapshot& other) = default;
 
-SyncCycleSnapshot::~SyncCycleSnapshot() {}
+SyncCycleSnapshot::~SyncCycleSnapshot() = default;
 
 std::unique_ptr<base::DictionaryValue> SyncCycleSnapshot::ToValue() const {
   std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
diff --git a/components/sync/engine/data_type_activation_response.cc b/components/sync/engine/data_type_activation_response.cc
index 570b94c..be027a7b 100644
--- a/components/sync/engine/data_type_activation_response.cc
+++ b/components/sync/engine/data_type_activation_response.cc
@@ -6,8 +6,8 @@
 
 namespace syncer {
 
-DataTypeActivationResponse::DataTypeActivationResponse() {}
+DataTypeActivationResponse::DataTypeActivationResponse() = default;
 
-DataTypeActivationResponse::~DataTypeActivationResponse() {}
+DataTypeActivationResponse::~DataTypeActivationResponse() = default;
 
 }  // namespace syncer
diff --git a/components/sync/engine/data_type_debug_info_listener.cc b/components/sync/engine/data_type_debug_info_listener.cc
index 62cdddc..459f2bab 100644
--- a/components/sync/engine/data_type_debug_info_listener.cc
+++ b/components/sync/engine/data_type_debug_info_listener.cc
@@ -12,6 +12,6 @@
 DataTypeConfigurationStats::DataTypeConfigurationStats(
     const DataTypeConfigurationStats& other) = default;
 
-DataTypeConfigurationStats::~DataTypeConfigurationStats() {}
+DataTypeConfigurationStats::~DataTypeConfigurationStats() = default;
 
 }  // namespace syncer
diff --git a/components/sync/engine/debug_info_event_listener.cc b/components/sync/engine/debug_info_event_listener.cc
index 710e75f5..793a99c 100644
--- a/components/sync/engine/debug_info_event_listener.cc
+++ b/components/sync/engine/debug_info_event_listener.cc
@@ -17,7 +17,7 @@
       cryptographer_has_pending_keys_(false),
       cryptographer_can_encrypt_(false) {}
 
-DebugInfoEventListener::~DebugInfoEventListener() {}
+DebugInfoEventListener::~DebugInfoEventListener() = default;
 
 void DebugInfoEventListener::InitializationComplete() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
@@ -169,26 +169,27 @@
     const std::vector<DataTypeConfigurationStats>& configuration_stats) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  for (size_t i = 0; i < configuration_stats.size(); ++i) {
-    DCHECK(ProtocolTypes().Has(configuration_stats[i].model_type));
+  for (const DataTypeConfigurationStats& configuration_stat :
+       configuration_stats) {
+    DCHECK(ProtocolTypes().Has(configuration_stat.model_type));
     sync_pb::DebugEventInfo association_event;
     sync_pb::DatatypeAssociationStats* datatype_stats =
         association_event.mutable_datatype_association_stats();
-    datatype_stats->set_data_type_id(GetSpecificsFieldNumberFromModelType(
-        configuration_stats[i].model_type));
+    datatype_stats->set_data_type_id(
+        GetSpecificsFieldNumberFromModelType(configuration_stat.model_type));
     datatype_stats->set_download_wait_time_us(
-        configuration_stats[i].download_wait_time.InMicroseconds());
+        configuration_stat.download_wait_time.InMicroseconds());
     datatype_stats->set_download_time_us(
-        configuration_stats[i].download_time.InMicroseconds());
+        configuration_stat.download_time.InMicroseconds());
 
     for (ModelType type :
-         configuration_stats[i].high_priority_types_configured_before) {
+         configuration_stat.high_priority_types_configured_before) {
       datatype_stats->add_high_priority_type_configured_before(
           GetSpecificsFieldNumberFromModelType(type));
     }
 
     for (ModelType type :
-         configuration_stats[i].same_priority_types_configured_before) {
+         configuration_stat.same_priority_types_configured_before) {
       datatype_stats->add_same_priority_type_configured_before(
           GetSpecificsFieldNumberFromModelType(type));
     }
diff --git a/components/sync/engine/entity_data_unittest.cc b/components/sync/engine/entity_data_unittest.cc
index 99689049..b66b86c 100644
--- a/components/sync/engine/entity_data_unittest.cc
+++ b/components/sync/engine/entity_data_unittest.cc
@@ -12,8 +12,8 @@
 
 class EntityDataTest : public testing::Test {
  protected:
-  EntityDataTest() {}
-  ~EntityDataTest() override {}
+  EntityDataTest() = default;
+  ~EntityDataTest() override = default;
 };
 
 TEST_F(EntityDataTest, IsDeleted) {
diff --git a/components/sync/engine/events/commit_request_event.cc b/components/sync/engine/events/commit_request_event.cc
index 48b156ae..d0d08d0 100644
--- a/components/sync/engine/events/commit_request_event.cc
+++ b/components/sync/engine/events/commit_request_event.cc
@@ -22,7 +22,7 @@
       contributing_types_(contributing_types),
       request_(request) {}
 
-CommitRequestEvent::~CommitRequestEvent() {}
+CommitRequestEvent::~CommitRequestEvent() = default;
 
 std::unique_ptr<ProtocolEvent> CommitRequestEvent::Clone() const {
   return std::make_unique<CommitRequestEvent>(timestamp_, num_items_,
diff --git a/components/sync/engine/events/commit_response_event.cc b/components/sync/engine/events/commit_response_event.cc
index b42ae3fc..4084214c 100644
--- a/components/sync/engine/events/commit_response_event.cc
+++ b/components/sync/engine/events/commit_response_event.cc
@@ -14,7 +14,7 @@
     const sync_pb::ClientToServerResponse& response)
     : timestamp_(timestamp), result_(result), response_(response) {}
 
-CommitResponseEvent::~CommitResponseEvent() {}
+CommitResponseEvent::~CommitResponseEvent() = default;
 
 std::unique_ptr<ProtocolEvent> CommitResponseEvent::Clone() const {
   return std::make_unique<CommitResponseEvent>(timestamp_, result_, response_);
diff --git a/components/sync/engine/events/configure_get_updates_request_event.cc b/components/sync/engine/events/configure_get_updates_request_event.cc
index 64b61e83..501f6ca 100644
--- a/components/sync/engine/events/configure_get_updates_request_event.cc
+++ b/components/sync/engine/events/configure_get_updates_request_event.cc
@@ -16,7 +16,7 @@
     const sync_pb::ClientToServerMessage& request)
     : timestamp_(timestamp), origin_(origin), request_(request) {}
 
-ConfigureGetUpdatesRequestEvent::~ConfigureGetUpdatesRequestEvent() {}
+ConfigureGetUpdatesRequestEvent::~ConfigureGetUpdatesRequestEvent() = default;
 
 std::unique_ptr<ProtocolEvent> ConfigureGetUpdatesRequestEvent::Clone() const {
   return std::make_unique<ConfigureGetUpdatesRequestEvent>(timestamp_, origin_,
diff --git a/components/sync/engine/events/get_updates_response_event.cc b/components/sync/engine/events/get_updates_response_event.cc
index adc19d1..8729403 100644
--- a/components/sync/engine/events/get_updates_response_event.cc
+++ b/components/sync/engine/events/get_updates_response_event.cc
@@ -15,7 +15,7 @@
     SyncerError error)
     : timestamp_(timestamp), response_(response), error_(error) {}
 
-GetUpdatesResponseEvent::~GetUpdatesResponseEvent() {}
+GetUpdatesResponseEvent::~GetUpdatesResponseEvent() = default;
 
 std::unique_ptr<ProtocolEvent> GetUpdatesResponseEvent::Clone() const {
   return std::make_unique<GetUpdatesResponseEvent>(timestamp_, response_,
diff --git a/components/sync/engine/events/normal_get_updates_request_event.cc b/components/sync/engine/events/normal_get_updates_request_event.cc
index 401c180..fc2f064d 100644
--- a/components/sync/engine/events/normal_get_updates_request_event.cc
+++ b/components/sync/engine/events/normal_get_updates_request_event.cc
@@ -41,7 +41,7 @@
       is_retry_, request_);
 }
 
-NormalGetUpdatesRequestEvent::~NormalGetUpdatesRequestEvent() {}
+NormalGetUpdatesRequestEvent::~NormalGetUpdatesRequestEvent() = default;
 
 base::Time NormalGetUpdatesRequestEvent::GetTimestamp() const {
   return timestamp_;
diff --git a/components/sync/engine/events/poll_get_updates_request_event.cc b/components/sync/engine/events/poll_get_updates_request_event.cc
index 045fa80..fe07a6bf 100644
--- a/components/sync/engine/events/poll_get_updates_request_event.cc
+++ b/components/sync/engine/events/poll_get_updates_request_event.cc
@@ -13,7 +13,7 @@
     const sync_pb::ClientToServerMessage& request)
     : timestamp_(timestamp), request_(request) {}
 
-PollGetUpdatesRequestEvent::~PollGetUpdatesRequestEvent() {}
+PollGetUpdatesRequestEvent::~PollGetUpdatesRequestEvent() = default;
 
 std::unique_ptr<ProtocolEvent> PollGetUpdatesRequestEvent::Clone() const {
   return std::make_unique<PollGetUpdatesRequestEvent>(timestamp_, request_);
diff --git a/components/sync/engine/events/protocol_event.cc b/components/sync/engine/events/protocol_event.cc
index 8efcbace..60aaa468 100644
--- a/components/sync/engine/events/protocol_event.cc
+++ b/components/sync/engine/events/protocol_event.cc
@@ -6,9 +6,9 @@
 
 namespace syncer {
 
-ProtocolEvent::ProtocolEvent() {}
+ProtocolEvent::ProtocolEvent() = default;
 
-ProtocolEvent::~ProtocolEvent() {}
+ProtocolEvent::~ProtocolEvent() = default;
 
 std::unique_ptr<base::DictionaryValue> ProtocolEvent::ToValue(
     bool include_specifics) const {
diff --git a/components/sync/engine/events/protocol_event_buffer.cc b/components/sync/engine/events/protocol_event_buffer.cc
index 56f60db2..e2c2c6b 100644
--- a/components/sync/engine/events/protocol_event_buffer.cc
+++ b/components/sync/engine/events/protocol_event_buffer.cc
@@ -10,9 +10,9 @@
 
 const size_t ProtocolEventBuffer::kBufferSize = 6;
 
-ProtocolEventBuffer::ProtocolEventBuffer() {}
+ProtocolEventBuffer::ProtocolEventBuffer() = default;
 
-ProtocolEventBuffer::~ProtocolEventBuffer() {}
+ProtocolEventBuffer::~ProtocolEventBuffer() = default;
 
 void ProtocolEventBuffer::RecordProtocolEvent(const ProtocolEvent& event) {
   buffer_.push_back(event.Clone());
diff --git a/components/sync/engine/events/protocol_event_buffer_unittest.cc b/components/sync/engine/events/protocol_event_buffer_unittest.cc
index 969d456..d06aee7 100644
--- a/components/sync/engine/events/protocol_event_buffer_unittest.cc
+++ b/components/sync/engine/events/protocol_event_buffer_unittest.cc
@@ -26,9 +26,9 @@
   ProtocolEventBuffer buffer_;
 };
 
-ProtocolEventBufferTest::ProtocolEventBufferTest() {}
+ProtocolEventBufferTest::ProtocolEventBufferTest() = default;
 
-ProtocolEventBufferTest::~ProtocolEventBufferTest() {}
+ProtocolEventBufferTest::~ProtocolEventBufferTest() = default;
 
 std::unique_ptr<ProtocolEvent> ProtocolEventBufferTest::MakeTestEvent(
     int64_t id) {
diff --git a/components/sync/engine/get_updates_delegate.cc b/components/sync/engine/get_updates_delegate.cc
index 9e32663b..9acd4cf 100644
--- a/components/sync/engine/get_updates_delegate.cc
+++ b/components/sync/engine/get_updates_delegate.cc
@@ -19,7 +19,7 @@
     const NudgeTracker& nudge_tracker)
     : nudge_tracker_(nudge_tracker) {}
 
-NormalGetUpdatesDelegate::~NormalGetUpdatesDelegate() {}
+NormalGetUpdatesDelegate::~NormalGetUpdatesDelegate() = default;
 
 // This function assumes the progress markers have already been populated.
 void NormalGetUpdatesDelegate::HelpPopulateGuMessage(
@@ -65,7 +65,7 @@
     sync_pb::SyncEnums::GetUpdatesOrigin origin)
     : origin_(origin) {}
 
-ConfigureGetUpdatesDelegate::~ConfigureGetUpdatesDelegate() {}
+ConfigureGetUpdatesDelegate::~ConfigureGetUpdatesDelegate() = default;
 
 void ConfigureGetUpdatesDelegate::HelpPopulateGuMessage(
     sync_pb::GetUpdatesMessage* get_updates) const {
@@ -85,9 +85,9 @@
                                                            request);
 }
 
-PollGetUpdatesDelegate::PollGetUpdatesDelegate() {}
+PollGetUpdatesDelegate::PollGetUpdatesDelegate() = default;
 
-PollGetUpdatesDelegate::~PollGetUpdatesDelegate() {}
+PollGetUpdatesDelegate::~PollGetUpdatesDelegate() = default;
 
 void PollGetUpdatesDelegate::HelpPopulateGuMessage(
     sync_pb::GetUpdatesMessage* get_updates) const {
diff --git a/components/sync/engine/get_updates_processor.cc b/components/sync/engine/get_updates_processor.cc
index c4a8560..828f6e9 100644
--- a/components/sync/engine/get_updates_processor.cc
+++ b/components/sync/engine/get_updates_processor.cc
@@ -180,7 +180,7 @@
                                          const GetUpdatesDelegate& delegate)
     : update_handler_map_(update_handler_map), delegate_(delegate) {}
 
-GetUpdatesProcessor::~GetUpdatesProcessor() {}
+GetUpdatesProcessor::~GetUpdatesProcessor() = default;
 
 SyncerError GetUpdatesProcessor::DownloadUpdates(ModelTypeSet* request_types,
                                                  SyncCycle* cycle) {
diff --git a/components/sync/engine/get_updates_processor_unittest.cc b/components/sync/engine/get_updates_processor_unittest.cc
index d8c44e1..82f5d7e 100644
--- a/components/sync/engine/get_updates_processor_unittest.cc
+++ b/components/sync/engine/get_updates_processor_unittest.cc
@@ -376,8 +376,8 @@
 // one of them.
 class GetUpdatesProcessorApplyUpdatesTest : public GetUpdatesProcessorTest {
  public:
-  GetUpdatesProcessorApplyUpdatesTest() {}
-  ~GetUpdatesProcessorApplyUpdatesTest() override {}
+  GetUpdatesProcessorApplyUpdatesTest() = default;
+  ~GetUpdatesProcessorApplyUpdatesTest() override = default;
 
   void SetUp() override {
     bookmarks_handler_ = AddUpdateHandler(BOOKMARKS);
@@ -453,8 +453,8 @@
 
 class DownloadUpdatesDebugInfoTest : public ::testing::Test {
  public:
-  DownloadUpdatesDebugInfoTest() {}
-  ~DownloadUpdatesDebugInfoTest() override {}
+  DownloadUpdatesDebugInfoTest() = default;
+  ~DownloadUpdatesDebugInfoTest() override = default;
 
   StatusController* status() { return &status_; }
 
diff --git a/components/sync/engine/loopback_server/loopback_server.cc b/components/sync/engine/loopback_server/loopback_server.cc
index ce2d1a2..162eccf 100644
--- a/components/sync/engine/loopback_server/loopback_server.cc
+++ b/components/sync/engine/loopback_server/loopback_server.cc
@@ -124,7 +124,7 @@
   UpdateSieve(const sync_pb::GetUpdatesMessage& message,
               const std::map<ModelType, int>& server_migration_versions)
       : UpdateSieve(MessageToVersionMap(message, server_migration_versions)) {}
-  ~UpdateSieve() {}
+  ~UpdateSieve() = default;
 
   // Verifies if MIGRATION_DONE should be exercised. It intentionally returns
   // migrations in the order that they were triggered.  Doing it this way
diff --git a/components/sync/engine/loopback_server/loopback_server_entity.cc b/components/sync/engine/loopback_server/loopback_server_entity.cc
index 824ad2c..72b4658 100644
--- a/components/sync/engine/loopback_server/loopback_server_entity.cc
+++ b/components/sync/engine/loopback_server/loopback_server_entity.cc
@@ -40,7 +40,7 @@
 
 namespace syncer {
 
-LoopbackServerEntity::~LoopbackServerEntity() {}
+LoopbackServerEntity::~LoopbackServerEntity() = default;
 
 // static
 std::unique_ptr<LoopbackServerEntity>
diff --git a/components/sync/engine/loopback_server/persistent_bookmark_entity.cc b/components/sync/engine/loopback_server/persistent_bookmark_entity.cc
index 9b082e8..f05693e8 100644
--- a/components/sync/engine/loopback_server/persistent_bookmark_entity.cc
+++ b/components/sync/engine/loopback_server/persistent_bookmark_entity.cc
@@ -28,7 +28,7 @@
 
 }  // namespace
 
-PersistentBookmarkEntity::~PersistentBookmarkEntity() {}
+PersistentBookmarkEntity::~PersistentBookmarkEntity() = default;
 
 // static
 std::unique_ptr<LoopbackServerEntity> PersistentBookmarkEntity::CreateNew(
diff --git a/components/sync/engine/loopback_server/persistent_permanent_entity.cc b/components/sync/engine/loopback_server/persistent_permanent_entity.cc
index 0d870be..a0c8f4b 100644
--- a/components/sync/engine/loopback_server/persistent_permanent_entity.cc
+++ b/components/sync/engine/loopback_server/persistent_permanent_entity.cc
@@ -25,7 +25,7 @@
 
 namespace syncer {
 
-PersistentPermanentEntity::~PersistentPermanentEntity() {}
+PersistentPermanentEntity::~PersistentPermanentEntity() = default;
 
 // static
 std::unique_ptr<LoopbackServerEntity> PersistentPermanentEntity::CreateNew(
diff --git a/components/sync/engine/loopback_server/persistent_tombstone_entity.cc b/components/sync/engine/loopback_server/persistent_tombstone_entity.cc
index 6d5dbdc..953f16b 100644
--- a/components/sync/engine/loopback_server/persistent_tombstone_entity.cc
+++ b/components/sync/engine/loopback_server/persistent_tombstone_entity.cc
@@ -16,7 +16,7 @@
 
 namespace syncer {
 
-PersistentTombstoneEntity::~PersistentTombstoneEntity() {}
+PersistentTombstoneEntity::~PersistentTombstoneEntity() = default;
 
 // static
 std::unique_ptr<LoopbackServerEntity>
diff --git a/components/sync/engine/loopback_server/persistent_unique_client_entity.cc b/components/sync/engine/loopback_server/persistent_unique_client_entity.cc
index d611400..4f9226a 100644
--- a/components/sync/engine/loopback_server/persistent_unique_client_entity.cc
+++ b/components/sync/engine/loopback_server/persistent_unique_client_entity.cc
@@ -31,7 +31,7 @@
   SetSpecifics(specifics);
 }
 
-PersistentUniqueClientEntity::~PersistentUniqueClientEntity() {}
+PersistentUniqueClientEntity::~PersistentUniqueClientEntity() = default;
 
 // static
 std::unique_ptr<LoopbackServerEntity>
diff --git a/components/sync/engine/model_type_connector_proxy.cc b/components/sync/engine/model_type_connector_proxy.cc
index 8c41fe1..b4bb968a 100644
--- a/components/sync/engine/model_type_connector_proxy.cc
+++ b/components/sync/engine/model_type_connector_proxy.cc
@@ -17,7 +17,7 @@
     const base::WeakPtr<ModelTypeConnector>& model_type_connector)
     : task_runner_(task_runner), model_type_connector_(model_type_connector) {}
 
-ModelTypeConnectorProxy::~ModelTypeConnectorProxy() {}
+ModelTypeConnectorProxy::~ModelTypeConnectorProxy() = default;
 
 void ModelTypeConnectorProxy::ConnectDataType(
     ModelType type,
diff --git a/components/sync/engine/model_type_processor_proxy.cc b/components/sync/engine/model_type_processor_proxy.cc
index 694669d..59e0d3b 100644
--- a/components/sync/engine/model_type_processor_proxy.cc
+++ b/components/sync/engine/model_type_processor_proxy.cc
@@ -17,7 +17,7 @@
     const scoped_refptr<base::SequencedTaskRunner>& task_runner)
     : processor_(processor), task_runner_(task_runner) {}
 
-ModelTypeProcessorProxy::~ModelTypeProcessorProxy() {}
+ModelTypeProcessorProxy::~ModelTypeProcessorProxy() = default;
 
 void ModelTypeProcessorProxy::ConnectSync(std::unique_ptr<CommitQueue> worker) {
   task_runner_->PostTask(
diff --git a/components/sync/engine/model_type_worker_unittest.cc b/components/sync/engine/model_type_worker_unittest.cc
index 46ad035..ba4d50d35 100644
--- a/components/sync/engine/model_type_worker_unittest.cc
+++ b/components/sync/engine/model_type_worker_unittest.cc
@@ -131,7 +131,7 @@
         is_encrypted_type_(is_encrypted_type),
         mock_server_(std::make_unique<SingleTypeMockServer>(model_type)) {}
 
-  ~ModelTypeWorkerTest() override {}
+  ~ModelTypeWorkerTest() override = default;
 
   // One of these Initialize functions should be called at the beginning of
   // each test.
diff --git a/components/sync/engine/net/http_bridge.cc b/components/sync/engine/net/http_bridge.cc
index ed7b724..674d73c 100644
--- a/components/sync/engine/net/http_bridge.cc
+++ b/components/sync/engine/net/http_bridge.cc
@@ -77,7 +77,7 @@
       request_succeeded(false),
       http_status_code(-1),
       net_error_code(-1) {}
-HttpBridge::URLFetchState::~URLFetchState() {}
+HttpBridge::URLFetchState::~URLFetchState() = default;
 
 HttpBridge::HttpBridge(const std::string& user_agent,
                        std::unique_ptr<network::PendingSharedURLLoaderFactory>
diff --git a/components/sync/engine/net/http_bridge_unittest.cc b/components/sync/engine/net/http_bridge_unittest.cc
index f77feee..626b2f44 100644
--- a/components/sync/engine/net/http_bridge_unittest.cc
+++ b/components/sync/engine/net/http_bridge_unittest.cc
@@ -50,8 +50,7 @@
 #endif  // defined(OS_ANDROID)
 class MAYBE_SyncHttpBridgeTest : public testing::Test {
  public:
-  MAYBE_SyncHttpBridgeTest()
-      : bridge_for_race_test_(nullptr), io_thread_("IO thread") {
+  MAYBE_SyncHttpBridgeTest() : io_thread_("IO thread") {
     test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
   }
 
@@ -93,7 +92,7 @@
         : HttpBridge(kUserAgent, nullptr /*PendingSharedURLLoaderFactory*/) {}
 
    protected:
-    ~CustomHttpBridge() override {}
+    ~CustomHttpBridge() override = default;
 
     void MakeAsynchronousPost() override {
       set_url_loader_factory_for_testing(
@@ -106,7 +105,7 @@
     }
   };
 
-  HttpBridge* bridge_for_race_test_;
+  HttpBridge* bridge_for_race_test_ = nullptr;
 
   base::test::TaskEnvironment task_environment_;
   variations::ScopedVariationsIdsProvider scoped_variations_ids_provider_{
@@ -142,7 +141,7 @@
   }
 
  private:
-  ~ShuntedHttpBridge() override {}
+  ~ShuntedHttpBridge() override = default;
 
   void CallOnURLFetchComplete() {
     ASSERT_TRUE(test_->GetIOThreadTaskRunner()->BelongsToCurrentThread());
diff --git a/components/sync/engine/sync_cycle_event.cc b/components/sync/engine/sync_cycle_event.cc
index f35d576..5e7e664d 100644
--- a/components/sync/engine/sync_cycle_event.cc
+++ b/components/sync/engine/sync_cycle_event.cc
@@ -8,6 +8,6 @@
 
 SyncCycleEvent::SyncCycleEvent(EventCause cause) : what_happened(cause) {}
 
-SyncCycleEvent::~SyncCycleEvent() {}
+SyncCycleEvent::~SyncCycleEvent() = default;
 
 }  // namespace syncer
diff --git a/components/sync/engine/sync_manager.cc b/components/sync/engine/sync_manager.cc
index 5d96663a..6cfbe10 100644
--- a/components/sync/engine/sync_manager.cc
+++ b/components/sync/engine/sync_manager.cc
@@ -6,7 +6,7 @@
 
 namespace syncer {
 
-SyncManager::Observer::~Observer() {}
+SyncManager::Observer::~Observer() = default;
 
 SyncManager::InitArgs::InitArgs()
     : enable_local_sync_backend(false),
@@ -14,10 +14,10 @@
       encryption_handler(nullptr),
       cancelation_signal(nullptr) {}
 
-SyncManager::InitArgs::~InitArgs() {}
+SyncManager::InitArgs::~InitArgs() = default;
 
-SyncManager::SyncManager() {}
+SyncManager::SyncManager() = default;
 
-SyncManager::~SyncManager() {}
+SyncManager::~SyncManager() = default;
 
 }  // namespace syncer
diff --git a/components/sync/engine/sync_manager_factory.cc b/components/sync/engine/sync_manager_factory.cc
index ee89ab4f..34f3edc 100644
--- a/components/sync/engine/sync_manager_factory.cc
+++ b/components/sync/engine/sync_manager_factory.cc
@@ -12,7 +12,7 @@
     network::NetworkConnectionTracker* network_connection_tracker)
     : network_connection_tracker_(network_connection_tracker) {}
 
-SyncManagerFactory::~SyncManagerFactory() {}
+SyncManagerFactory::~SyncManagerFactory() = default;
 
 std::unique_ptr<SyncManager> SyncManagerFactory::CreateSyncManager(
     const std::string& name) {
diff --git a/components/sync/engine/sync_manager_impl_unittest.cc b/components/sync/engine/sync_manager_impl_unittest.cc
index 2763366..331d104 100644
--- a/components/sync/engine/sync_manager_impl_unittest.cc
+++ b/components/sync/engine/sync_manager_impl_unittest.cc
@@ -162,7 +162,7 @@
 
   ~SyncManagerImplTest() override = default;
 
-  void SetUp() {
+  void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
 
     extensions_activity_ = new ExtensionsActivity();
diff --git a/components/sync/engine/sync_scheduler_impl_unittest.cc b/components/sync/engine/sync_scheduler_impl_unittest.cc
index 5c82a7f7..feb9d8b 100644
--- a/components/sync/engine/sync_scheduler_impl_unittest.cc
+++ b/components/sync/engine/sync_scheduler_impl_unittest.cc
@@ -234,9 +234,7 @@
       : task_environment_(
             base::test::SingleThreadTaskEnvironment::ThreadPoolExecutionMode::
                 ASYNC,
-            base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME),
-        syncer_(nullptr),
-        delay_(nullptr) {}
+            base::test::SingleThreadTaskEnvironment::TimeSource::MOCK_TIME) {}
 
   class MockDelayProvider : public BackoffDelayProvider {
    public:
@@ -457,8 +455,8 @@
   std::unique_ptr<SyncCycleContext> context_;
   std::unique_ptr<SyncSchedulerImpl> scheduler_;
   MockNudgeHandler mock_nudge_handler_;
-  MockSyncer* syncer_;
-  MockDelayProvider* delay_;
+  MockSyncer* syncer_ = nullptr;
+  MockDelayProvider* delay_ = nullptr;
   scoped_refptr<ExtensionsActivity> extensions_activity_;
   base::WeakPtrFactory<SyncSchedulerImplTest> weak_ptr_factory_{this};
 };
diff --git a/components/sync/engine/syncer.cc b/components/sync/engine/syncer.cc
index e4177b24..61b570d7 100644
--- a/components/sync/engine/syncer.cc
+++ b/components/sync/engine/syncer.cc
@@ -35,7 +35,7 @@
 Syncer::Syncer(CancelationSignal* cancelation_signal)
     : cancelation_signal_(cancelation_signal), is_syncing_(false) {}
 
-Syncer::~Syncer() {}
+Syncer::~Syncer() = default;
 
 bool Syncer::IsSyncing() const {
   return is_syncing_;
diff --git a/components/sync/engine/syncer_unittest.cc b/components/sync/engine/syncer_unittest.cc
index 2caa234..06e58ebd 100644
--- a/components/sync/engine/syncer_unittest.cc
+++ b/components/sync/engine/syncer_unittest.cc
@@ -83,10 +83,7 @@
                    public SyncCycle::Delegate,
                    public SyncEngineEventListener {
  protected:
-  SyncerTest()
-      : extensions_activity_(new ExtensionsActivity),
-        syncer_(nullptr),
-        last_client_invalidation_hint_buffer_size_(10) {}
+  SyncerTest() = default;
 
   // SyncCycle::Delegate implementation.
   void OnThrottled(const base::TimeDelta& throttle_duration) override {
@@ -243,12 +240,13 @@
   base::test::SingleThreadTaskEnvironment task_environment_;
 
   FakeSyncEncryptionHandler encryption_handler_;
-  scoped_refptr<ExtensionsActivity> extensions_activity_;
+  scoped_refptr<ExtensionsActivity> extensions_activity_ =
+      new ExtensionsActivity;
   std::unique_ptr<MockConnectionManager> mock_server_;
   CancelationSignal cancelation_signal_;
   std::map<ModelType, MockModelTypeProcessor> mock_model_type_processors_;
 
-  Syncer* syncer_;
+  Syncer* syncer_ = nullptr;
 
   std::unique_ptr<SyncCycle> cycle_;
   MockNudgeHandler mock_nudge_handler_;
@@ -258,7 +256,7 @@
   base::TimeDelta last_poll_interval_received_;
   base::TimeDelta last_sessions_commit_delay_;
   base::TimeDelta last_bookmarks_commit_delay_;
-  int last_client_invalidation_hint_buffer_size_;
+  int last_client_invalidation_hint_buffer_size_ = 10;
 
   ModelTypeSet enabled_datatypes_;
   NudgeTracker nudge_tracker_;
diff --git a/components/sync/model/blocking_model_type_store_impl.cc b/components/sync/model/blocking_model_type_store_impl.cc
index 5ffdedc..661a196 100644
--- a/components/sync/model/blocking_model_type_store_impl.cc
+++ b/components/sync/model/blocking_model_type_store_impl.cc
@@ -106,7 +106,7 @@
         leveldb_write_batch_(std::make_unique<leveldb::WriteBatch>()),
         metadata_change_list_(type, leveldb_write_batch_.get()) {}
 
-  ~LevelDbWriteBatch() override {}
+  ~LevelDbWriteBatch() override = default;
 
   ModelType GetModelType() const { return type_; }
 
diff --git a/components/sync/model/client_tag_based_model_type_processor_unittest.cc b/components/sync/model/client_tag_based_model_type_processor_unittest.cc
index 41304b6d..cd71b27 100644
--- a/components/sync/model/client_tag_based_model_type_processor_unittest.cc
+++ b/components/sync/model/client_tag_based_model_type_processor_unittest.cc
@@ -267,7 +267,7 @@
 //   metadata in storage on the bridge side.
 class ClientTagBasedModelTypeProcessorTest : public ::testing::Test {
  public:
-  ClientTagBasedModelTypeProcessorTest() {}
+  ClientTagBasedModelTypeProcessorTest() = default;
   ~ClientTagBasedModelTypeProcessorTest() override { CheckPostConditions(); }
 
   void SetUp() override {
diff --git a/components/sync/model/data_type_error_handler_impl.cc b/components/sync/model/data_type_error_handler_impl.cc
index abdbe96..b6752a2 100644
--- a/components/sync/model/data_type_error_handler_impl.cc
+++ b/components/sync/model/data_type_error_handler_impl.cc
@@ -17,7 +17,7 @@
       dump_stack_(dump_stack),
       sync_callback_(sync_callback) {}
 
-DataTypeErrorHandlerImpl::~DataTypeErrorHandlerImpl() {}
+DataTypeErrorHandlerImpl::~DataTypeErrorHandlerImpl() = default;
 
 void DataTypeErrorHandlerImpl::OnUnrecoverableError(const SyncError& error) {
   if (!dump_stack_.is_null())
diff --git a/components/sync/model/entity_change.cc b/components/sync/model/entity_change.cc
index 95f26381..6b08f4a 100644
--- a/components/sync/model/entity_change.cc
+++ b/components/sync/model/entity_change.cc
@@ -38,6 +38,6 @@
                            EntityData data)
     : storage_key_(storage_key), type_(type), data_(std::move(data)) {}
 
-EntityChange::~EntityChange() {}
+EntityChange::~EntityChange() = default;
 
 }  // namespace syncer
diff --git a/components/sync/model/forwarding_model_type_controller_delegate.cc b/components/sync/model/forwarding_model_type_controller_delegate.cc
index 110e4ad..3a7c741c 100644
--- a/components/sync/model/forwarding_model_type_controller_delegate.cc
+++ b/components/sync/model/forwarding_model_type_controller_delegate.cc
@@ -16,7 +16,7 @@
 }
 
 ForwardingModelTypeControllerDelegate::
-    ~ForwardingModelTypeControllerDelegate() {}
+    ~ForwardingModelTypeControllerDelegate() = default;
 
 void ForwardingModelTypeControllerDelegate::OnSyncStarting(
     const DataTypeActivationRequest& request,
diff --git a/components/sync/model/in_memory_metadata_change_list.cc b/components/sync/model/in_memory_metadata_change_list.cc
index 730340e..82044d24 100644
--- a/components/sync/model/in_memory_metadata_change_list.cc
+++ b/components/sync/model/in_memory_metadata_change_list.cc
@@ -8,8 +8,8 @@
 
 namespace syncer {
 
-InMemoryMetadataChangeList::InMemoryMetadataChangeList() {}
-InMemoryMetadataChangeList::~InMemoryMetadataChangeList() {}
+InMemoryMetadataChangeList::InMemoryMetadataChangeList() = default;
+InMemoryMetadataChangeList::~InMemoryMetadataChangeList() = default;
 
 void InMemoryMetadataChangeList::TransferChangesTo(MetadataChangeList* other) {
   DCHECK(other);
diff --git a/components/sync/model/metadata_batch.cc b/components/sync/model/metadata_batch.cc
index 227f7ef4..5c8f877 100644
--- a/components/sync/model/metadata_batch.cc
+++ b/components/sync/model/metadata_batch.cc
@@ -9,11 +9,11 @@
 
 namespace syncer {
 
-MetadataBatch::MetadataBatch() {}
+MetadataBatch::MetadataBatch() = default;
 
 MetadataBatch::MetadataBatch(MetadataBatch&& other) = default;
 
-MetadataBatch::~MetadataBatch() {}
+MetadataBatch::~MetadataBatch() = default;
 
 const EntityMetadataMap& MetadataBatch::GetAllMetadata() const {
   return metadata_map_;
diff --git a/components/sync/model/model_type_store_base.cc b/components/sync/model/model_type_store_base.cc
index 2de24509..f3dae0af 100644
--- a/components/sync/model/model_type_store_base.cc
+++ b/components/sync/model/model_type_store_base.cc
@@ -14,9 +14,9 @@
   return std::make_unique<InMemoryMetadataChangeList>();
 }
 
-ModelTypeStoreBase::WriteBatch::WriteBatch() {}
+ModelTypeStoreBase::WriteBatch::WriteBatch() = default;
 
-ModelTypeStoreBase::WriteBatch::~WriteBatch() {}
+ModelTypeStoreBase::WriteBatch::~WriteBatch() = default;
 
 void ModelTypeStoreBase::WriteBatch::TakeMetadataChangesFrom(
     std::unique_ptr<MetadataChangeList> mcl) {
diff --git a/components/sync/model/model_type_sync_bridge.cc b/components/sync/model/model_type_sync_bridge.cc
index 76ce2ddb..b6d63fac 100644
--- a/components/sync/model/model_type_sync_bridge.cc
+++ b/components/sync/model/model_type_sync_bridge.cc
@@ -19,7 +19,7 @@
   change_processor_->OnModelStarting(this);
 }
 
-ModelTypeSyncBridge::~ModelTypeSyncBridge() {}
+ModelTypeSyncBridge::~ModelTypeSyncBridge() = default;
 
 void ModelTypeSyncBridge::OnSyncStarting(
     const DataTypeActivationRequest& request) {}
diff --git a/components/sync/model/model_type_sync_bridge_unittest.cc b/components/sync/model/model_type_sync_bridge_unittest.cc
index 955b6057..5a007df8 100644
--- a/components/sync/model/model_type_sync_bridge_unittest.cc
+++ b/components/sync/model/model_type_sync_bridge_unittest.cc
@@ -26,7 +26,7 @@
  public:
   ModelTypeSyncBridgeTest()
       : bridge_(mock_processor_.CreateForwardingProcessor()) {}
-  ~ModelTypeSyncBridgeTest() override {}
+  ~ModelTypeSyncBridgeTest() override = default;
 
   StubModelTypeSyncBridge* bridge() { return &bridge_; }
   MockModelTypeChangeProcessor* processor() { return &mock_processor_; }
diff --git a/components/sync/model/mutable_data_batch.cc b/components/sync/model/mutable_data_batch.cc
index 3d63746..d3dce26 100644
--- a/components/sync/model/mutable_data_batch.cc
+++ b/components/sync/model/mutable_data_batch.cc
@@ -8,13 +8,13 @@
 
 namespace syncer {
 
-MutableDataBatch::MutableDataBatch() {}
+MutableDataBatch::MutableDataBatch() = default;
 
-MutableDataBatch::~MutableDataBatch() {}
+MutableDataBatch::~MutableDataBatch() = default;
 
 void MutableDataBatch::Put(const std::string& storage_key,
                            std::unique_ptr<EntityData> specifics) {
-  key_data_pairs_.push_back(KeyAndData(storage_key, std::move(specifics)));
+  key_data_pairs_.emplace_back(storage_key, std::move(specifics));
 }
 
 bool MutableDataBatch::HasNext() const {
diff --git a/components/sync/model/processor_entity.cc b/components/sync/model/processor_entity.cc
index bad14d5..222c425 100644
--- a/components/sync/model/processor_entity.cc
+++ b/components/sync/model/processor_entity.cc
@@ -73,7 +73,7 @@
   metadata_ = std::move(metadata);
 }
 
-ProcessorEntity::~ProcessorEntity() {}
+ProcessorEntity::~ProcessorEntity() = default;
 
 void ProcessorEntity::SetStorageKey(const std::string& storage_key) {
   DCHECK(storage_key_.empty());
diff --git a/components/sync/model/proxy_model_type_controller_delegate.cc b/components/sync/model/proxy_model_type_controller_delegate.cc
index f0d3c1a..2d160ce 100644
--- a/components/sync/model/proxy_model_type_controller_delegate.cc
+++ b/components/sync/model/proxy_model_type_controller_delegate.cc
@@ -74,7 +74,7 @@
   DCHECK(task_runner_);
 }
 
-ProxyModelTypeControllerDelegate::~ProxyModelTypeControllerDelegate() {}
+ProxyModelTypeControllerDelegate::~ProxyModelTypeControllerDelegate() = default;
 
 void ProxyModelTypeControllerDelegate::OnSyncStarting(
     const DataTypeActivationRequest& request,
diff --git a/components/sync/model/sync_change.cc b/components/sync/model/sync_change.cc
index 5461e9e..2395246 100644
--- a/components/sync/model/sync_change.cc
+++ b/components/sync/model/sync_change.cc
@@ -17,7 +17,7 @@
   DCHECK(IsValid()) << " from " << from_here.ToString();
 }
 
-SyncChange::~SyncChange() {}
+SyncChange::~SyncChange() = default;
 
 bool SyncChange::IsValid() const {
   // TODO(crbug.com/1152824): This implementation could be simplified if the
diff --git a/components/sync/model/sync_error.cc b/components/sync/model/sync_error.cc
index f6ff489..d36ab56 100644
--- a/components/sync/model/sync_error.cc
+++ b/components/sync/model/sync_error.cc
@@ -29,7 +29,7 @@
   Copy(other);
 }
 
-SyncError::~SyncError() {}
+SyncError::~SyncError() = default;
 
 SyncError& SyncError::operator=(const SyncError& other) {
   if (this == &other) {
diff --git a/components/sync/model/syncable_service_based_bridge.cc b/components/sync/model/syncable_service_based_bridge.cc
index 78deb819..6c25ed30 100644
--- a/components/sync/model/syncable_service_based_bridge.cc
+++ b/components/sync/model/syncable_service_based_bridge.cc
@@ -118,7 +118,7 @@
     DCHECK(other);
   }
 
-  ~LocalChangeProcessor() override {}
+  ~LocalChangeProcessor() override = default;
 
   absl::optional<ModelError> ProcessSyncChanges(
       const base::Location& from_here,
diff --git a/components/sync/model/syncable_service_based_bridge_unittest.cc b/components/sync/model/syncable_service_based_bridge_unittest.cc
index 10a21a9c..7f16889 100644
--- a/components/sync/model/syncable_service_based_bridge_unittest.cc
+++ b/components/sync/model/syncable_service_based_bridge_unittest.cc
@@ -99,7 +99,7 @@
             });
   }
 
-  ~SyncableServiceBasedBridgeTest() override {}
+  ~SyncableServiceBasedBridgeTest() override = default;
 
   void InitializeBridge(ModelType model_type = kModelType) {
     real_processor_ =
diff --git a/components/sync/nigori/nigori.cc b/components/sync/nigori/nigori.cc
index 513f9347..92d616f 100644
--- a/components/sync/nigori/nigori.cc
+++ b/components/sync/nigori/nigori.cc
@@ -182,7 +182,7 @@
   return true;
 }
 
-Nigori::~Nigori() {}
+Nigori::~Nigori() = default;
 
 // static
 std::unique_ptr<Nigori> Nigori::CreateByDerivation(
diff --git a/components/sync/nigori/nigori_unittest.cc b/components/sync/nigori/nigori_unittest.cc
index 359a55b..0f5b0d1 100644
--- a/components/sync/nigori/nigori_unittest.cc
+++ b/components/sync/nigori/nigori_unittest.cc
@@ -23,7 +23,7 @@
 
 class FakeTickClock : public base::TickClock {
  public:
-  FakeTickClock() : call_count_(0) {}
+  FakeTickClock() = default;
 
   // How much the mock clock advances after each call to the mocked
   // base::TimeTicks::Now(). We do this because we are testing functions which
@@ -40,7 +40,7 @@
   int call_count() const { return call_count_; }
 
  private:
-  mutable int call_count_;
+  mutable int call_count_ = 0;
 };
 
 constexpr base::TimeDelta FakeTickClock::kTicksAdvanceAfterEachCall;
diff --git a/components/sync/protocol/proto_memory_estimations.cc b/components/sync/protocol/proto_memory_estimations.cc
index c7f7f800..cf000b1 100644
--- a/components/sync/protocol/proto_memory_estimations.cc
+++ b/components/sync/protocol/proto_memory_estimations.cc
@@ -29,7 +29,7 @@
 //
 class MemoryUsageVisitor {
  public:
-  MemoryUsageVisitor() : memory_usage_(0) {}
+  MemoryUsageVisitor() = default;
 
   size_t memory_usage() const { return memory_usage_; }
 
@@ -109,7 +109,7 @@
   }
 
  private:
-  size_t memory_usage_;
+  size_t memory_usage_ = 0;
 };
 
 }  // namespace
diff --git a/components/sync/protocol/proto_value_conversions.cc b/components/sync/protocol/proto_value_conversions.cc
index 476828b..48574ad 100644
--- a/components/sync/protocol/proto_value_conversions.cc
+++ b/components/sync/protocol/proto_value_conversions.cc
@@ -123,8 +123,8 @@
 //
 class ToValueVisitor {
  public:
-  ToValueVisitor(bool include_specifics = true,
-                 base::DictionaryValue* value = nullptr)
+  explicit ToValueVisitor(bool include_specifics = true,
+                          base::DictionaryValue* value = nullptr)
       : value_(value), include_specifics_(include_specifics) {}
 
   template <class P>
diff --git a/components/sync/protocol/sync_protocol_error.cc b/components/sync/protocol/sync_protocol_error.cc
index 34f00dc..ca09158 100644
--- a/components/sync/protocol/sync_protocol_error.cc
+++ b/components/sync/protocol/sync_protocol_error.cc
@@ -51,7 +51,7 @@
 
 SyncProtocolError::SyncProtocolError(const SyncProtocolError& other) = default;
 
-SyncProtocolError::~SyncProtocolError() {}
+SyncProtocolError::~SyncProtocolError() = default;
 
 std::unique_ptr<base::DictionaryValue> SyncProtocolError::ToValue() const {
   auto value = std::make_unique<base::DictionaryValue>();
diff --git a/components/sync/test/engine/fake_model_type_connector.cc b/components/sync/test/engine/fake_model_type_connector.cc
index c886c13..0e86998 100644
--- a/components/sync/test/engine/fake_model_type_connector.cc
+++ b/components/sync/test/engine/fake_model_type_connector.cc
@@ -8,9 +8,9 @@
 
 namespace syncer {
 
-FakeModelTypeConnector::FakeModelTypeConnector() {}
+FakeModelTypeConnector::FakeModelTypeConnector() = default;
 
-FakeModelTypeConnector::~FakeModelTypeConnector() {}
+FakeModelTypeConnector::~FakeModelTypeConnector() = default;
 
 void FakeModelTypeConnector::ConnectDataType(
     ModelType type,
diff --git a/components/sync/test/engine/fake_model_type_processor.cc b/components/sync/test/engine/fake_model_type_processor.cc
index 590c25e4..7a4029a7 100644
--- a/components/sync/test/engine/fake_model_type_processor.cc
+++ b/components/sync/test/engine/fake_model_type_processor.cc
@@ -11,8 +11,8 @@
 
 namespace syncer {
 
-FakeModelTypeProcessor::FakeModelTypeProcessor() {}
-FakeModelTypeProcessor::~FakeModelTypeProcessor() {}
+FakeModelTypeProcessor::FakeModelTypeProcessor() = default;
+FakeModelTypeProcessor::~FakeModelTypeProcessor() = default;
 
 void FakeModelTypeProcessor::ConnectSync(std::unique_ptr<CommitQueue> worker) {}
 
diff --git a/components/sync/test/engine/fake_sync_manager.cc b/components/sync/test/engine/fake_sync_manager.cc
index a932da96..930dd4b 100644
--- a/components/sync/test/engine/fake_sync_manager.cc
+++ b/components/sync/test/engine/fake_sync_manager.cc
@@ -31,7 +31,7 @@
       configure_fail_types_(configure_fail_types),
       last_configure_reason_(CONFIGURE_REASON_UNKNOWN) {}
 
-FakeSyncManager::~FakeSyncManager() {}
+FakeSyncManager::~FakeSyncManager() = default;
 
 ModelTypeSet FakeSyncManager::GetAndResetDownloadedTypes() {
   ModelTypeSet downloaded_types = downloaded_types_;
diff --git a/components/sync/test/engine/mock_model_type_processor.cc b/components/sync/test/engine/mock_model_type_processor.cc
index bb83394..dc1c331 100644
--- a/components/sync/test/engine/mock_model_type_processor.cc
+++ b/components/sync/test/engine/mock_model_type_processor.cc
@@ -77,8 +77,8 @@
 }
 
 void MockModelTypeProcessor::RunQueuedTasks() {
-  for (auto it = pending_tasks_.begin(); it != pending_tasks_.end(); ++it) {
-    std::move(*it).Run();
+  for (base::OnceClosure& pending_task : pending_tasks_) {
+    std::move(pending_task).Run();
   }
   pending_tasks_.clear();
 }
@@ -254,10 +254,9 @@
     const FailedCommitResponseDataList& error_response_list) {
   received_commit_responses_.push_back(committed_response_list);
   type_states_received_on_commit_.push_back(type_state);
-  for (auto it = committed_response_list.begin();
-       it != committed_response_list.end(); ++it) {
-    const ClientTagHash& tag_hash = it->client_tag_hash;
-    commit_response_items_.insert(std::make_pair(tag_hash, *it));
+  for (const CommitResponseData& response : committed_response_list) {
+    const ClientTagHash& tag_hash = response.client_tag_hash;
+    commit_response_items_.insert(std::make_pair(tag_hash, response));
 
     if (pending_deleted_hashes_.find(tag_hash) !=
         pending_deleted_hashes_.end()) {
@@ -269,8 +268,8 @@
       pending_deleted_hashes_.erase(tag_hash);
     } else {
       // Server wins.  Set the model's base version.
-      SetBaseVersion(tag_hash, it->response_version);
-      SetServerAssignedId(tag_hash, it->id);
+      SetBaseVersion(tag_hash, response.response_version);
+      SetServerAssignedId(tag_hash, response.id);
     }
   }
 }
@@ -279,13 +278,13 @@
     const sync_pb::ModelTypeState& type_state,
     UpdateResponseDataList response_list) {
   type_states_received_on_update_.push_back(type_state);
-  for (auto it = response_list.begin(); it != response_list.end(); ++it) {
-    const ClientTagHash& client_tag_hash = it->entity.client_tag_hash;
+  for (const UpdateResponseData& response : response_list) {
+    const ClientTagHash& client_tag_hash = response.entity.client_tag_hash;
     // Server wins.  Set the model's base version.
-    SetBaseVersion(client_tag_hash, it->response_version);
-    SetServerAssignedId(client_tag_hash, it->entity.id);
+    SetBaseVersion(client_tag_hash, response.response_version);
+    SetServerAssignedId(client_tag_hash, response.entity.id);
 
-    update_response_items_.insert(std::make_pair(client_tag_hash, &(*it)));
+    update_response_items_.insert(std::make_pair(client_tag_hash, &response));
   }
   received_update_responses_.push_back(std::move(response_list));
 }
diff --git a/components/sync/test/engine/mock_model_type_worker.cc b/components/sync/test/engine/mock_model_type_worker.cc
index 85f94e8b..b7ca14e 100644
--- a/components/sync/test/engine/mock_model_type_worker.cc
+++ b/components/sync/test/engine/mock_model_type_worker.cc
@@ -24,7 +24,7 @@
   model_type_state_.set_initial_sync_done(true);
 }
 
-MockModelTypeWorker::~MockModelTypeWorker() {}
+MockModelTypeWorker::~MockModelTypeWorker() = default;
 
 void MockModelTypeWorker::NudgeForCommit() {
   processor_->GetLocalChanges(
diff --git a/components/sync/test/engine/mock_nudge_handler.cc b/components/sync/test/engine/mock_nudge_handler.cc
index 992940d3..f3d4c9b 100644
--- a/components/sync/test/engine/mock_nudge_handler.cc
+++ b/components/sync/test/engine/mock_nudge_handler.cc
@@ -9,7 +9,7 @@
 MockNudgeHandler::MockNudgeHandler()
     : num_initial_nudges_(0), num_commit_nudges_(0) {}
 
-MockNudgeHandler::~MockNudgeHandler() {}
+MockNudgeHandler::~MockNudgeHandler() = default;
 
 void MockNudgeHandler::NudgeForInitialDownload(ModelType type) {
   num_initial_nudges_++;
diff --git a/components/sync/test/engine/mock_sync_engine.cc b/components/sync/test/engine/mock_sync_engine.cc
index 98ffe1e..4c36f3e 100644
--- a/components/sync/test/engine/mock_sync_engine.cc
+++ b/components/sync/test/engine/mock_sync_engine.cc
@@ -6,8 +6,8 @@
 
 namespace syncer {
 
-MockSyncEngine::MockSyncEngine() {}
+MockSyncEngine::MockSyncEngine() = default;
 
-MockSyncEngine::~MockSyncEngine() {}
+MockSyncEngine::~MockSyncEngine() = default;
 
 }  // namespace syncer
diff --git a/components/sync/test/engine/mock_update_handler.cc b/components/sync/test/engine/mock_update_handler.cc
index 2ba3b4af..898568c 100644
--- a/components/sync/test/engine/mock_update_handler.cc
+++ b/components/sync/test/engine/mock_update_handler.cc
@@ -15,7 +15,7 @@
   progress_marker_.set_token(token_str);
 }
 
-MockUpdateHandler::~MockUpdateHandler() {}
+MockUpdateHandler::~MockUpdateHandler() = default;
 
 bool MockUpdateHandler::IsInitialSyncEnded() const {
   return false;
diff --git a/components/sync/test/engine/single_type_mock_server.cc b/components/sync/test/engine/single_type_mock_server.cc
index 924c783..463c309 100644
--- a/components/sync/test/engine/single_type_mock_server.cc
+++ b/components/sync/test/engine/single_type_mock_server.cc
@@ -19,7 +19,7 @@
       type_root_id_(ModelTypeToRootTag(type)),
       progress_marker_token_("non_null_progress_token") {}
 
-SingleTypeMockServer::~SingleTypeMockServer() {}
+SingleTypeMockServer::~SingleTypeMockServer() = default;
 
 sync_pb::SyncEntity SingleTypeMockServer::TypeRootUpdate() {
   sync_pb::SyncEntity entity;
diff --git a/components/sync/test/fake_server/fake_server_http_post_provider.cc b/components/sync/test/fake_server/fake_server_http_post_provider.cc
index cee14f2..3cd4b07 100644
--- a/components/sync/test/fake_server/fake_server_http_post_provider.cc
+++ b/components/sync/test/fake_server/fake_server_http_post_provider.cc
@@ -42,7 +42,7 @@
           base::WaitableEvent::InitialState::NOT_SIGNALED),
       aborted_(false) {}
 
-FakeServerHttpPostProvider::~FakeServerHttpPostProvider() {}
+FakeServerHttpPostProvider::~FakeServerHttpPostProvider() = default;
 
 void FakeServerHttpPostProvider::SetExtraRequestHeaders(const char* headers) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/components/sync/test/fake_server/fake_server_verifier.cc b/components/sync/test/fake_server/fake_server_verifier.cc
index 41b2c5e..9136d72 100644
--- a/components/sync/test/fake_server/fake_server_verifier.cc
+++ b/components/sync/test/fake_server/fake_server_verifier.cc
@@ -65,7 +65,7 @@
 FakeServerVerifier::FakeServerVerifier(FakeServer* fake_server)
     : fake_server_(fake_server) {}
 
-FakeServerVerifier::~FakeServerVerifier() {}
+FakeServerVerifier::~FakeServerVerifier() = default;
 
 AssertionResult FakeServerVerifier::VerifyEntityCountByType(
     size_t expected_count,
diff --git a/components/sync/test/fake_server/sessions_hierarchy.cc b/components/sync/test/fake_server/sessions_hierarchy.cc
index 2c17943e..b06ba42 100644
--- a/components/sync/test/fake_server/sessions_hierarchy.cc
+++ b/components/sync/test/fake_server/sessions_hierarchy.cc
@@ -8,7 +8,7 @@
 
 namespace fake_server {
 
-SessionsHierarchy::SessionsHierarchy() {}
+SessionsHierarchy::SessionsHierarchy() = default;
 
 SessionsHierarchy::SessionsHierarchy(const SessionsHierarchy& other) = default;
 
@@ -16,7 +16,7 @@
     std::initializer_list<std::multiset<std::string>> windows)
     : windows_(windows) {}
 
-SessionsHierarchy::~SessionsHierarchy() {}
+SessionsHierarchy::~SessionsHierarchy() = default;
 
 void SessionsHierarchy::AddWindow(const std::string& tab) {
   windows_.insert({tab});
diff --git a/components/sync/test/mock_invalidation.cc b/components/sync/test/mock_invalidation.cc
index 213c21f..aa0a79b 100644
--- a/components/sync/test/mock_invalidation.cc
+++ b/components/sync/test/mock_invalidation.cc
@@ -21,7 +21,7 @@
       new MockInvalidation(false, version, payload));
 }
 
-MockInvalidation::~MockInvalidation() {}
+MockInvalidation::~MockInvalidation() = default;
 
 bool MockInvalidation::IsUnknownVersion() const {
   return is_unknown_version_;
diff --git a/components/sync/test/mock_invalidation_tracker.cc b/components/sync/test/mock_invalidation_tracker.cc
index d44b004..d22376e 100644
--- a/components/sync/test/mock_invalidation_tracker.cc
+++ b/components/sync/test/mock_invalidation_tracker.cc
@@ -25,7 +25,7 @@
 
 MockInvalidationTracker::MockInvalidationTracker() : next_id_(0) {}
 
-MockInvalidationTracker::~MockInvalidationTracker() {}
+MockInvalidationTracker::~MockInvalidationTracker() = default;
 
 void MockInvalidationTracker::Acknowledge(int invalidation_id) {
   acknowledged_.insert(invalidation_id);
diff --git a/components/sync/test/model/fake_model_type_controller_delegate.cc b/components/sync/test/model/fake_model_type_controller_delegate.cc
index 68a81a9..3e02246 100644
--- a/components/sync/test/model/fake_model_type_controller_delegate.cc
+++ b/components/sync/test/model/fake_model_type_controller_delegate.cc
@@ -17,7 +17,7 @@
 FakeModelTypeControllerDelegate::FakeModelTypeControllerDelegate(ModelType type)
     : type_(type) {}
 
-FakeModelTypeControllerDelegate::~FakeModelTypeControllerDelegate() {}
+FakeModelTypeControllerDelegate::~FakeModelTypeControllerDelegate() = default;
 
 void FakeModelTypeControllerDelegate::SetModelTypeStateForActivationResponse(
     const sync_pb::ModelTypeState& model_type_state) {
diff --git a/components/sync/test/model/fake_model_type_sync_bridge.cc b/components/sync/test/model/fake_model_type_sync_bridge.cc
index df5ab47..e480c8f 100644
--- a/components/sync/test/model/fake_model_type_sync_bridge.cc
+++ b/components/sync/test/model/fake_model_type_sync_bridge.cc
@@ -35,7 +35,7 @@
  public:
   explicit TestMetadataChangeList(FakeModelTypeSyncBridge::Store* db)
       : db_(db) {}
-  ~TestMetadataChangeList() override {}
+  ~TestMetadataChangeList() override = default;
 
   // MetadataChangeList implementation.
   void UpdateModelTypeState(
@@ -96,8 +96,8 @@
   return entity_data;
 }
 
-FakeModelTypeSyncBridge::Store::Store() {}
-FakeModelTypeSyncBridge::Store::~Store() {}
+FakeModelTypeSyncBridge::Store::Store() = default;
+FakeModelTypeSyncBridge::Store::~Store() = default;
 
 void FakeModelTypeSyncBridge::Store::PutData(const std::string& key,
                                              const EntityData& data) {
diff --git a/components/sync/test/model/fake_sync_change_processor.cc b/components/sync/test/model/fake_sync_change_processor.cc
index a33c3307..dc12dcf 100644
--- a/components/sync/test/model/fake_sync_change_processor.cc
+++ b/components/sync/test/model/fake_sync_change_processor.cc
@@ -9,9 +9,9 @@
 
 namespace syncer {
 
-FakeSyncChangeProcessor::FakeSyncChangeProcessor() {}
+FakeSyncChangeProcessor::FakeSyncChangeProcessor() = default;
 
-FakeSyncChangeProcessor::~FakeSyncChangeProcessor() {}
+FakeSyncChangeProcessor::~FakeSyncChangeProcessor() = default;
 
 absl::optional<ModelError> FakeSyncChangeProcessor::ProcessSyncChanges(
     const base::Location& from_here,
diff --git a/components/sync/test/model/mock_model_type_change_processor.cc b/components/sync/test/model/mock_model_type_change_processor.cc
index 41e906b..85a925f8 100644
--- a/components/sync/test/model/mock_model_type_change_processor.cc
+++ b/components/sync/test/model/mock_model_type_change_processor.cc
@@ -21,7 +21,7 @@
   // |other| must not be nullptr and must outlive this object.
   explicit ForwardingModelTypeChangeProcessor(ModelTypeChangeProcessor* other)
       : other_(other) {}
-  ~ForwardingModelTypeChangeProcessor() override {}
+  ~ForwardingModelTypeChangeProcessor() override = default;
 
   void Put(const std::string& client_tag,
            std::unique_ptr<EntityData> entity_data,
@@ -97,9 +97,9 @@
 
 }  // namespace
 
-MockModelTypeChangeProcessor::MockModelTypeChangeProcessor() {}
+MockModelTypeChangeProcessor::MockModelTypeChangeProcessor() = default;
 
-MockModelTypeChangeProcessor::~MockModelTypeChangeProcessor() {}
+MockModelTypeChangeProcessor::~MockModelTypeChangeProcessor() = default;
 
 std::unique_ptr<ModelTypeChangeProcessor>
 MockModelTypeChangeProcessor::CreateForwardingProcessor() {
diff --git a/components/sync/test/model/stub_model_type_sync_bridge.cc b/components/sync/test/model/stub_model_type_sync_bridge.cc
index 57f1000..671d9f38 100644
--- a/components/sync/test/model/stub_model_type_sync_bridge.cc
+++ b/components/sync/test/model/stub_model_type_sync_bridge.cc
@@ -15,7 +15,7 @@
     std::unique_ptr<ModelTypeChangeProcessor> change_processor)
     : ModelTypeSyncBridge(std::move(change_processor)) {}
 
-StubModelTypeSyncBridge::~StubModelTypeSyncBridge() {}
+StubModelTypeSyncBridge::~StubModelTypeSyncBridge() = default;
 
 std::unique_ptr<MetadataChangeList>
 StubModelTypeSyncBridge::CreateMetadataChangeList() {
diff --git a/components/sync/test/model/sync_change_processor_wrapper_for_test.cc b/components/sync/test/model/sync_change_processor_wrapper_for_test.cc
index f362f56..f011623 100644
--- a/components/sync/test/model/sync_change_processor_wrapper_for_test.cc
+++ b/components/sync/test/model/sync_change_processor_wrapper_for_test.cc
@@ -25,7 +25,8 @@
   DCHECK(wrapped);
 }
 
-SyncChangeProcessorWrapperForTest::~SyncChangeProcessorWrapperForTest() {}
+SyncChangeProcessorWrapperForTest::~SyncChangeProcessorWrapperForTest() =
+    default;
 
 absl::optional<ModelError>
 SyncChangeProcessorWrapperForTest::ProcessSyncChanges(
diff --git a/components/sync/test/model/sync_error_factory_mock.cc b/components/sync/test/model/sync_error_factory_mock.cc
index 34b29f7..1506a3e2 100644
--- a/components/sync/test/model/sync_error_factory_mock.cc
+++ b/components/sync/test/model/sync_error_factory_mock.cc
@@ -6,8 +6,8 @@
 
 namespace syncer {
 
-SyncErrorFactoryMock::SyncErrorFactoryMock() {}
+SyncErrorFactoryMock::SyncErrorFactoryMock() = default;
 
-SyncErrorFactoryMock::~SyncErrorFactoryMock() {}
+SyncErrorFactoryMock::~SyncErrorFactoryMock() = default;
 
 }  // namespace syncer
diff --git a/components/sync/test/model/test_model_type_store_service.cc b/components/sync/test/model/test_model_type_store_service.cc
index 61dfbdb..014d9c6 100644
--- a/components/sync/test/model/test_model_type_store_service.cc
+++ b/components/sync/test/model/test_model_type_store_service.cc
@@ -16,7 +16,7 @@
   DCHECK(sync_data_path_.CreateUniqueTempDir());
 }
 
-TestModelTypeStoreService::~TestModelTypeStoreService() {}
+TestModelTypeStoreService::~TestModelTypeStoreService() = default;
 
 const base::FilePath& TestModelTypeStoreService::GetSyncDataPath() const {
   return sync_data_path_.GetPath();
diff --git a/components/sync/test/trackable_mock_invalidation.cc b/components/sync/test/trackable_mock_invalidation.cc
index 3afce9b1..18ff16e 100644
--- a/components/sync/test/trackable_mock_invalidation.cc
+++ b/components/sync/test/trackable_mock_invalidation.cc
@@ -18,7 +18,7 @@
       tracker_(tracker),
       tracking_id_(tracking_id) {}
 
-TrackableMockInvalidation::~TrackableMockInvalidation() {}
+TrackableMockInvalidation::~TrackableMockInvalidation() = default;
 
 void TrackableMockInvalidation::Acknowledge() {
   if (tracker_) {
diff --git a/components/sync_bookmarks/bookmark_model_merger.cc b/components/sync_bookmarks/bookmark_model_merger.cc
index f86849c..a7adc21c 100644
--- a/components/sync_bookmarks/bookmark_model_merger.cc
+++ b/components/sync_bookmarks/bookmark_model_merger.cc
@@ -538,7 +538,7 @@
       "Sync.BookmarkModelMerger.ReachableInputUpdates", num_updates_in_forest);
 }
 
-BookmarkModelMerger::~BookmarkModelMerger() {}
+BookmarkModelMerger::~BookmarkModelMerger() = default;
 
 void BookmarkModelMerger::Merge() {
   TRACE_EVENT0("sync", "BookmarkModelMerger::Merge");
diff --git a/components/sync_bookmarks/bookmark_sync_service.cc b/components/sync_bookmarks/bookmark_sync_service.cc
index aefc065..8c30bca3 100644
--- a/components/sync_bookmarks/bookmark_sync_service.cc
+++ b/components/sync_bookmarks/bookmark_sync_service.cc
@@ -18,7 +18,7 @@
           bookmark_undo_service);
 }
 
-BookmarkSyncService::~BookmarkSyncService() {}
+BookmarkSyncService::~BookmarkSyncService() = default;
 
 std::string BookmarkSyncService::EncodeBookmarkSyncMetadata() {
   if (!bookmark_model_type_processor_) {
diff --git a/components/sync_device_info/device_count_metrics_provider.cc b/components/sync_device_info/device_count_metrics_provider.cc
index abe6c02..11347f9 100644
--- a/components/sync_device_info/device_count_metrics_provider.cc
+++ b/components/sync_device_info/device_count_metrics_provider.cc
@@ -15,7 +15,7 @@
     const ProvideTrackersCallback& provide_trackers)
     : provide_trackers_(provide_trackers) {}
 
-DeviceCountMetricsProvider::~DeviceCountMetricsProvider() {}
+DeviceCountMetricsProvider::~DeviceCountMetricsProvider() = default;
 
 int DeviceCountMetricsProvider::MaxActiveDeviceCount() const {
   std::vector<const DeviceInfoTracker*> trackers;
diff --git a/components/sync_device_info/device_info.cc b/components/sync_device_info/device_info.cc
index fc034e9..e0fc68c 100644
--- a/components/sync_device_info/device_info.cc
+++ b/components/sync_device_info/device_info.cc
@@ -100,7 +100,7 @@
       fcm_registration_token_(fcm_registration_token),
       interested_data_types_(interested_data_types) {}
 
-DeviceInfo::~DeviceInfo() {}
+DeviceInfo::~DeviceInfo() = default;
 
 const std::string& DeviceInfo::guid() const {
   return guid_;
diff --git a/components/sync_device_info/device_info_prefs.cc b/components/sync_device_info/device_info_prefs.cc
index 6df1fa5..147a5f99 100644
--- a/components/sync_device_info/device_info_prefs.cc
+++ b/components/sync_device_info/device_info_prefs.cc
@@ -58,7 +58,7 @@
   DCHECK(clock_);
 }
 
-DeviceInfoPrefs::~DeviceInfoPrefs() {}
+DeviceInfoPrefs::~DeviceInfoPrefs() = default;
 
 bool DeviceInfoPrefs::IsRecentLocalCacheGuid(
     const std::string& cache_guid) const {
diff --git a/components/sync_device_info/device_info_sync_bridge.cc b/components/sync_device_info/device_info_sync_bridge.cc
index 1d41e23..e223cbc7 100644
--- a/components/sync_device_info/device_info_sync_bridge.cc
+++ b/components/sync_device_info/device_info_sync_bridge.cc
@@ -555,9 +555,9 @@
 std::vector<std::unique_ptr<DeviceInfo>>
 DeviceInfoSyncBridge::GetAllDeviceInfo() const {
   std::vector<std::unique_ptr<DeviceInfo>> list;
-  for (auto iter = all_data_.begin(); iter != all_data_.end(); ++iter) {
-    if (IsChromeClient(*iter->second)) {
-      list.push_back(SpecificsToModel(*iter->second));
+  for (const auto& id_and_specifics : all_data_) {
+    if (IsChromeClient(*id_and_specifics.second)) {
+      list.push_back(SpecificsToModel(*id_and_specifics.second));
     }
   }
   return list;
diff --git a/components/sync_device_info/local_device_info_provider_impl_unittest.cc b/components/sync_device_info/local_device_info_provider_impl_unittest.cc
index a96bc5b..bc3e514d 100644
--- a/components/sync_device_info/local_device_info_provider_impl_unittest.cc
+++ b/components/sync_device_info/local_device_info_provider_impl_unittest.cc
@@ -47,7 +47,7 @@
   MockDeviceInfoSyncClient(const MockDeviceInfoSyncClient&) = delete;
   MockDeviceInfoSyncClient& operator=(const MockDeviceInfoSyncClient&) = delete;
 
-  ~MockDeviceInfoSyncClient() = default;
+  ~MockDeviceInfoSyncClient() override = default;
 
   MOCK_METHOD(std::string, GetSigninScopedDeviceId, (), (const override));
   MOCK_METHOD(bool, GetSendTabToSelfReceivingEnabled, (), (const override));
@@ -72,8 +72,8 @@
 
 class LocalDeviceInfoProviderImplTest : public testing::Test {
  public:
-  LocalDeviceInfoProviderImplTest() {}
-  ~LocalDeviceInfoProviderImplTest() override {}
+  LocalDeviceInfoProviderImplTest() = default;
+  ~LocalDeviceInfoProviderImplTest() override = default;
 
   void SetUp() override {
     provider_ = std::make_unique<LocalDeviceInfoProviderImpl>(
diff --git a/components/sync_preferences/pref_model_associator.cc b/components/sync_preferences/pref_model_associator.cc
index 16af36f..c82a0b0 100644
--- a/components/sync_preferences/pref_model_associator.cc
+++ b/components/sync_preferences/pref_model_associator.cc
@@ -226,9 +226,9 @@
   }
 
   // Go through and build sync data for any remaining preferences.
-  for (auto pref_name_iter = remaining_preferences.begin();
-       pref_name_iter != remaining_preferences.end(); ++pref_name_iter) {
-    InitPrefAndAssociate(syncer::SyncData(), *pref_name_iter, &new_changes);
+  for (const std::string& remaining_preference : remaining_preferences) {
+    InitPrefAndAssociate(syncer::SyncData(), remaining_preference,
+                         &new_changes);
   }
 
   for (const std::string& legacy_pref_name : legacy_model_type_preferences_) {
@@ -367,9 +367,7 @@
     syncer::ModelType type) const {
   DCHECK_EQ(type_, type);
   syncer::SyncDataList current_data;
-  for (auto iter = synced_preferences_.begin();
-       iter != synced_preferences_.end(); ++iter) {
-    std::string name = *iter;
+  for (const std::string& name : synced_preferences_) {
     const PrefService::Preference* pref = pref_service_->FindPreference(name);
     DCHECK(pref);
     if (!pref->IsUserControlled() || pref->IsDefaultValue())
diff --git a/components/sync_preferences/pref_model_associator_unittest.cc b/components/sync_preferences/pref_model_associator_unittest.cc
index b2aceb5..411ba10 100644
--- a/components/sync_preferences/pref_model_associator_unittest.cc
+++ b/components/sync_preferences/pref_model_associator_unittest.cc
@@ -28,13 +28,13 @@
 
 class TestPrefModelAssociatorClient : public PrefModelAssociatorClient {
  public:
-  TestPrefModelAssociatorClient() {}
+  TestPrefModelAssociatorClient() = default;
 
   TestPrefModelAssociatorClient(const TestPrefModelAssociatorClient&) = delete;
   TestPrefModelAssociatorClient& operator=(
       const TestPrefModelAssociatorClient&) = delete;
 
-  ~TestPrefModelAssociatorClient() override {}
+  ~TestPrefModelAssociatorClient() override = default;
 
   // PrefModelAssociatorClient implementation.
   bool IsMergeableListPreference(const std::string& pref_name) const override {
diff --git a/components/sync_preferences/pref_service_mock_factory.cc b/components/sync_preferences/pref_service_mock_factory.cc
index 0b64d3f..dbd339d 100644
--- a/components/sync_preferences/pref_service_mock_factory.cc
+++ b/components/sync_preferences/pref_service_mock_factory.cc
@@ -12,6 +12,6 @@
   user_prefs_ = new TestingPrefStore;
 }
 
-PrefServiceMockFactory::~PrefServiceMockFactory() {}
+PrefServiceMockFactory::~PrefServiceMockFactory() = default;
 
 }  // namespace sync_preferences
diff --git a/components/sync_preferences/pref_service_syncable_factory.cc b/components/sync_preferences/pref_service_syncable_factory.cc
index 5757e28..9f7b4f01 100644
--- a/components/sync_preferences/pref_service_syncable_factory.cc
+++ b/components/sync_preferences/pref_service_syncable_factory.cc
@@ -20,9 +20,9 @@
 
 namespace sync_preferences {
 
-PrefServiceSyncableFactory::PrefServiceSyncableFactory() {}
+PrefServiceSyncableFactory::PrefServiceSyncableFactory() = default;
 
-PrefServiceSyncableFactory::~PrefServiceSyncableFactory() {}
+PrefServiceSyncableFactory::~PrefServiceSyncableFactory() = default;
 
 void PrefServiceSyncableFactory::SetManagedPolicies(
     policy::PolicyService* service,
diff --git a/components/sync_preferences/pref_service_syncable_unittest.cc b/components/sync_preferences/pref_service_syncable_unittest.cc
index 4bce55d..4dff491 100644
--- a/components/sync_preferences/pref_service_syncable_unittest.cc
+++ b/components/sync_preferences/pref_service_syncable_unittest.cc
@@ -195,7 +195,7 @@
 
 class PrefServiceSyncableTest : public testing::Test {
  public:
-  PrefServiceSyncableTest() : pref_sync_service_(nullptr) {}
+  PrefServiceSyncableTest() = default;
 
   void SetUp() override {
     prefs_.registry()->RegisterStringPref(kUnsyncedPreferenceName,
@@ -263,7 +263,7 @@
  protected:
   TestingPrefServiceSyncable prefs_;
 
-  PrefModelAssociator* pref_sync_service_;
+  PrefModelAssociator* pref_sync_service_ = nullptr;
 };
 
 TEST_F(PrefServiceSyncableTest, CreatePrefSyncData) {
@@ -363,13 +363,13 @@
 
 class TestPrefModelAssociatorClient : public PrefModelAssociatorClient {
  public:
-  TestPrefModelAssociatorClient() {}
+  TestPrefModelAssociatorClient() = default;
 
   TestPrefModelAssociatorClient(const TestPrefModelAssociatorClient&) = delete;
   TestPrefModelAssociatorClient& operator=(
       const TestPrefModelAssociatorClient&) = delete;
 
-  ~TestPrefModelAssociatorClient() override {}
+  ~TestPrefModelAssociatorClient() override = default;
 
   // PrefModelAssociatorClient implementation.
   bool IsMergeableListPreference(const std::string& pref_name) const override {
@@ -397,12 +397,7 @@
 class PrefServiceSyncableMergeTest : public testing::Test {
  public:
   PrefServiceSyncableMergeTest()
-      : pref_registry_(
-            base::MakeRefCounted<user_prefs::PrefRegistrySyncable>()),
-        pref_notifier_(new PrefNotifierImpl),
-        managed_prefs_(base::MakeRefCounted<TestingPrefStore>()),
-        user_prefs_(base::MakeRefCounted<TestingPrefStore>()),
-        prefs_(
+      : prefs_(
             std::unique_ptr<PrefNotifierImpl>(pref_notifier_),
             std::make_unique<PrefValueStore>(managed_prefs_.get(),
                                              new TestingPrefStore,
@@ -416,8 +411,7 @@
             pref_registry_,
             &client_,
             /*read_error_callback=*/base::DoNothing(),
-            /*async=*/false),
-        pref_sync_service_(nullptr) {}
+            /*async=*/false) {}
 
   void SetUp() override {
     pref_registry_->RegisterStringPref(kUnsyncedPreferenceName,
@@ -498,14 +492,17 @@
   }
 
  protected:
-  scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry_;
+  scoped_refptr<user_prefs::PrefRegistrySyncable> pref_registry_ =
+      base::MakeRefCounted<user_prefs::PrefRegistrySyncable>();
   // Owned by prefs_;
-  PrefNotifierImpl* pref_notifier_;
-  scoped_refptr<TestingPrefStore> managed_prefs_;
-  scoped_refptr<TestingPrefStore> user_prefs_;
+  PrefNotifierImpl* const pref_notifier_ = new PrefNotifierImpl;
+  scoped_refptr<TestingPrefStore> managed_prefs_ =
+      base::MakeRefCounted<TestingPrefStore>();
+  scoped_refptr<TestingPrefStore> user_prefs_ =
+      base::MakeRefCounted<TestingPrefStore>();
   TestPrefModelAssociatorClient client_;
   PrefServiceSyncable prefs_;
-  PrefModelAssociator* pref_sync_service_;
+  PrefModelAssociator* pref_sync_service_ = nullptr;
 };
 
 TEST_F(PrefServiceSyncableMergeTest, ShouldMergeSelectedListValues) {
@@ -634,8 +631,8 @@
 
 class ShouldNotBeNotifedObserver : public SyncedPrefObserver {
  public:
-  ShouldNotBeNotifedObserver() {}
-  ~ShouldNotBeNotifedObserver() {}
+  ShouldNotBeNotifedObserver() = default;
+  ~ShouldNotBeNotifedObserver() = default;
 
   void OnSyncedPrefChanged(const std::string& path, bool from_sync) override {
     ADD_FAILURE() << "Unexpected notification about a pref change with path: '"
diff --git a/components/sync_preferences/testing_pref_service_syncable.cc b/components/sync_preferences/testing_pref_service_syncable.cc
index fc7edf9..e2fd19c 100644
--- a/components/sync_preferences/testing_pref_service_syncable.cc
+++ b/components/sync_preferences/testing_pref_service_syncable.cc
@@ -76,7 +76,7 @@
           pref_registry,
           pref_notifier) {}
 
-TestingPrefServiceSyncable::~TestingPrefServiceSyncable() {}
+TestingPrefServiceSyncable::~TestingPrefServiceSyncable() = default;
 
 user_prefs::PrefRegistrySyncable* TestingPrefServiceSyncable::registry() {
   return static_cast<user_prefs::PrefRegistrySyncable*>(
diff --git a/components/sync_sessions/local_session_event_handler_impl.cc b/components/sync_sessions/local_session_event_handler_impl.cc
index a093ead..bd6668d 100644
--- a/components/sync_sessions/local_session_event_handler_impl.cc
+++ b/components/sync_sessions/local_session_event_handler_impl.cc
@@ -107,7 +107,7 @@
   }
 }
 
-LocalSessionEventHandlerImpl::~LocalSessionEventHandlerImpl() {}
+LocalSessionEventHandlerImpl::~LocalSessionEventHandlerImpl() = default;
 
 void LocalSessionEventHandlerImpl::OnSessionRestoreComplete() {
   std::unique_ptr<WriteBatch> batch = delegate_->CreateLocalSessionWriteBatch();
diff --git a/components/sync_sessions/mock_sync_sessions_client.cc b/components/sync_sessions/mock_sync_sessions_client.cc
index d6bc31e..ce156bc 100644
--- a/components/sync_sessions/mock_sync_sessions_client.cc
+++ b/components/sync_sessions/mock_sync_sessions_client.cc
@@ -12,6 +12,6 @@
       .WillByDefault(testing::Return(true));
 }
 
-MockSyncSessionsClient::~MockSyncSessionsClient() {}
+MockSyncSessionsClient::~MockSyncSessionsClient() = default;
 
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/open_tabs_ui_delegate.cc b/components/sync_sessions/open_tabs_ui_delegate.cc
index 2308430..32f0412b 100644
--- a/components/sync_sessions/open_tabs_ui_delegate.cc
+++ b/components/sync_sessions/open_tabs_ui_delegate.cc
@@ -6,6 +6,6 @@
 
 namespace sync_sessions {
 
-OpenTabsUIDelegate::~OpenTabsUIDelegate() {}
+OpenTabsUIDelegate::~OpenTabsUIDelegate() = default;
 
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/open_tabs_ui_delegate_impl.cc b/components/sync_sessions/open_tabs_ui_delegate_impl.cc
index 8dfe14a..ada40be6 100644
--- a/components/sync_sessions/open_tabs_ui_delegate_impl.cc
+++ b/components/sync_sessions/open_tabs_ui_delegate_impl.cc
@@ -5,6 +5,7 @@
 #include "components/sync_sessions/open_tabs_ui_delegate_impl.h"
 
 #include <algorithm>
+#include <memory>
 
 #include "components/sync_sessions/sync_sessions_client.h"
 #include "components/sync_sessions/synced_session_tracker.h"
@@ -36,7 +37,7 @@
       session_tracker_(session_tracker),
       delete_foreign_session_cb_(delete_foreign_session_cb) {}
 
-OpenTabsUIDelegateImpl::~OpenTabsUIDelegateImpl() {}
+OpenTabsUIDelegateImpl::~OpenTabsUIDelegateImpl() = default;
 
 bool OpenTabsUIDelegateImpl::GetAllForeignSessions(
     std::vector<const SyncedSession*>* sessions) {
@@ -69,17 +70,15 @@
   // Prune those tabs that are not syncable or are NewTabPage, then sort them
   // from most recent to least recent, independent of which window the tabs were
   // from.
-  for (size_t j = 0; j < windows.size(); ++j) {
-    const sessions::SessionWindow* window = windows[j];
-    for (size_t t = 0; t < window->tabs.size(); ++t) {
-      sessions::SessionTab* const tab = window->tabs[t].get();
+  for (const sessions::SessionWindow* window : windows) {
+    for (const std::unique_ptr<sessions::SessionTab>& tab : window->tabs) {
       if (tab->navigations.empty())
         continue;
       const sessions::SerializedNavigationEntry& current_navigation =
           tab->navigations.at(tab->normalized_navigation_index());
       if (!sessions_client_->ShouldSyncURL(current_navigation.virtual_url()))
         continue;
-      tabs->push_back(tab);
+      tabs->push_back(tab.get());
     }
   }
   std::stable_sort(tabs->begin(), tabs->end(), TabsRecencyComparator);
diff --git a/components/sync_sessions/proxy_tabs_data_type_controller.cc b/components/sync_sessions/proxy_tabs_data_type_controller.cc
index 6a0a5c7..9ab28dc7 100644
--- a/components/sync_sessions/proxy_tabs_data_type_controller.cc
+++ b/components/sync_sessions/proxy_tabs_data_type_controller.cc
@@ -21,7 +21,7 @@
       state_changed_cb_(state_changed_cb),
       state_(NOT_RUNNING) {}
 
-ProxyTabsDataTypeController::~ProxyTabsDataTypeController() {}
+ProxyTabsDataTypeController::~ProxyTabsDataTypeController() = default;
 
 void ProxyTabsDataTypeController::LoadModels(
     const syncer::ConfigureContext& configure_context,
diff --git a/components/sync_sessions/session_store_unittest.cc b/components/sync_sessions/session_store_unittest.cc
index d68edc82..65b9bc7 100644
--- a/components/sync_sessions/session_store_unittest.cc
+++ b/components/sync_sessions/session_store_unittest.cc
@@ -176,7 +176,7 @@
                 underlying_store_.get())));
   }
 
-  ~SessionStoreOpenTest() override {}
+  ~SessionStoreOpenTest() override = default;
 
   base::test::SingleThreadTaskEnvironment task_environment_;
   TestingPrefServiceSimple pref_service_;
diff --git a/components/sync_sessions/session_sync_bridge.cc b/components/sync_sessions/session_sync_bridge.cc
index caaf1e30..4af5f47 100644
--- a/components/sync_sessions/session_sync_bridge.cc
+++ b/components/sync_sessions/session_sync_bridge.cc
@@ -63,7 +63,7 @@
     DCHECK(processor_->IsTrackingMetadata());
   }
 
-  ~LocalSessionWriteBatch() override {}
+  ~LocalSessionWriteBatch() override = default;
 
   // WriteBatch implementation.
   void Delete(int tab_node_id) override {
@@ -454,8 +454,8 @@
   change_processor()->ReportError(error);
 }
 
-SessionSyncBridge::SyncingState::SyncingState() {}
+SessionSyncBridge::SyncingState::SyncingState() = default;
 
-SessionSyncBridge::SyncingState::~SyncingState() {}
+SessionSyncBridge::SyncingState::~SyncingState() = default;
 
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/session_sync_bridge_unittest.cc b/components/sync_sessions/session_sync_bridge_unittest.cc
index a35cd1c8..f690cb5 100644
--- a/components/sync_sessions/session_sync_bridge_unittest.cc
+++ b/components/sync_sessions/session_sync_bridge_unittest.cc
@@ -184,7 +184,7 @@
     EXPECT_CALL(mock_processor_, ReportError).Times(0);
   }
 
-  ~SessionSyncBridgeTest() override {}
+  ~SessionSyncBridgeTest() override = default;
 
   void InitializeBridge() {
     real_processor_ =
diff --git a/components/sync_sessions/session_sync_prefs.cc b/components/sync_sessions/session_sync_prefs.cc
index 365a502..240fa53 100644
--- a/components/sync_sessions/session_sync_prefs.cc
+++ b/components/sync_sessions/session_sync_prefs.cc
@@ -26,7 +26,7 @@
   DCHECK(pref_service);
 }
 
-SessionSyncPrefs::~SessionSyncPrefs() {}
+SessionSyncPrefs::~SessionSyncPrefs() = default;
 
 std::string SessionSyncPrefs::GetLegacySyncSessionsGUID() const {
   return pref_service_->GetString(kLegacySyncSessionsGUID);
diff --git a/components/sync_sessions/session_sync_service_impl.cc b/components/sync_sessions/session_sync_service_impl.cc
index 9ac5dc2..f042614 100644
--- a/components/sync_sessions/session_sync_service_impl.cc
+++ b/components/sync_sessions/session_sync_service_impl.cc
@@ -31,7 +31,7 @@
           base::BindRepeating(&syncer::ReportUnrecoverableError, channel)));
 }
 
-SessionSyncServiceImpl::~SessionSyncServiceImpl() {}
+SessionSyncServiceImpl::~SessionSyncServiceImpl() = default;
 
 syncer::GlobalIdMapper* SessionSyncServiceImpl::GetGlobalIdMapper() const {
   return bridge_->GetGlobalIdMapper();
diff --git a/components/sync_sessions/session_sync_test_helper.cc b/components/sync_sessions/session_sync_test_helper.cc
index cb86ee6a..f43f620 100644
--- a/components/sync_sessions/session_sync_test_helper.cc
+++ b/components/sync_sessions/session_sync_test_helper.cc
@@ -40,8 +40,8 @@
   window->set_window_id(window_id.id());
   window->set_selected_tab_index(0);
   window->set_browser_type(sync_pb::SessionWindow_BrowserType_TYPE_TABBED);
-  for (auto iter = tab_list.begin(); iter != tab_list.end(); ++iter) {
-    window->add_tab(iter->id());
+  for (const SessionID& tab_id : tab_list) {
+    window->add_tab(tab_id.id());
   }
 }
 
diff --git a/components/sync_sessions/sync_sessions_client.cc b/components/sync_sessions/sync_sessions_client.cc
index 91ef3b8..afbad55 100644
--- a/components/sync_sessions/sync_sessions_client.cc
+++ b/components/sync_sessions/sync_sessions_client.cc
@@ -6,7 +6,7 @@
 
 namespace sync_sessions {
 
-SyncSessionsClient::SyncSessionsClient() {}
-SyncSessionsClient::~SyncSessionsClient() {}
+SyncSessionsClient::SyncSessionsClient() = default;
+SyncSessionsClient::~SyncSessionsClient() = default;
 
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/synced_session.cc b/components/sync_sessions/synced_session.cc
index 85b52d8..f9f0ecc 100644
--- a/components/sync_sessions/synced_session.cc
+++ b/components/sync_sessions/synced_session.cc
@@ -330,9 +330,9 @@
   return sync_data;
 }
 
-SyncedSessionWindow::SyncedSessionWindow() {}
+SyncedSessionWindow::SyncedSessionWindow() = default;
 
-SyncedSessionWindow::~SyncedSessionWindow() {}
+SyncedSessionWindow::~SyncedSessionWindow() = default;
 
 sync_pb::SessionWindow SyncedSessionWindow::ToSessionWindowProto() const {
   sync_pb::SessionWindow sync_data;
@@ -349,7 +349,7 @@
 SyncedSession::SyncedSession()
     : session_tag("invalid"), device_type(sync_pb::SyncEnums::TYPE_UNSET) {}
 
-SyncedSession::~SyncedSession() {}
+SyncedSession::~SyncedSession() = default;
 
 sync_pb::SessionHeader SyncedSession::ToSessionHeaderProto() const {
   sync_pb::SessionHeader header;
diff --git a/components/sync_sessions/synced_session_tracker.cc b/components/sync_sessions/synced_session_tracker.cc
index ae24ad3..3bb7990 100644
--- a/components/sync_sessions/synced_session_tracker.cc
+++ b/components/sync_sessions/synced_session_tracker.cc
@@ -50,10 +50,9 @@
 // Presentable means |foreign_session| must have syncable content.
 bool IsPresentable(SyncSessionsClient* sessions_client,
                    const SyncedSession& foreign_session) {
-  for (auto iter = foreign_session.windows.begin();
-       iter != foreign_session.windows.end(); ++iter) {
+  for (const auto& id_and_window : foreign_session.windows) {
     if (ShouldSyncSessionWindow(sessions_client,
-                                iter->second->wrapped_window)) {
+                                id_and_window.second->wrapped_window)) {
       return true;
     }
   }
@@ -155,14 +154,14 @@
 
 }  // namespace
 
-SyncedSessionTracker::TrackedSession::TrackedSession() {}
+SyncedSessionTracker::TrackedSession::TrackedSession() = default;
 
-SyncedSessionTracker::TrackedSession::~TrackedSession() {}
+SyncedSessionTracker::TrackedSession::~TrackedSession() = default;
 
 SyncedSessionTracker::SyncedSessionTracker(SyncSessionsClient* sessions_client)
     : sessions_client_(sessions_client) {}
 
-SyncedSessionTracker::~SyncedSessionTracker() {}
+SyncedSessionTracker::~SyncedSessionTracker() = default;
 
 void SyncedSessionTracker::InitLocalSession(
     const std::string& local_session_tag,
diff --git a/components/sync_sessions/synced_session_tracker_unittest.cc b/components/sync_sessions/synced_session_tracker_unittest.cc
index c2997f13..9c79901 100644
--- a/components/sync_sessions/synced_session_tracker_unittest.cc
+++ b/components/sync_sessions/synced_session_tracker_unittest.cc
@@ -63,7 +63,7 @@
 class SyncedSessionTrackerTest : public testing::Test {
  public:
   SyncedSessionTrackerTest() : tracker_(&sessions_client_) {}
-  ~SyncedSessionTrackerTest() override {}
+  ~SyncedSessionTrackerTest() override = default;
 
   TabNodePool* GetLocalTabNodePool() {
     return &tracker_.LookupTrackedSession(tracker_.local_session_tag_)
diff --git a/components/sync_sessions/synced_tab_delegate.cc b/components/sync_sessions/synced_tab_delegate.cc
index e36a0d9..e974d7a 100644
--- a/components/sync_sessions/synced_tab_delegate.cc
+++ b/components/sync_sessions/synced_tab_delegate.cc
@@ -6,7 +6,7 @@
 
 namespace sync_sessions {
 
-SyncedTabDelegate::SyncedTabDelegate() {}
-SyncedTabDelegate::~SyncedTabDelegate() {}
+SyncedTabDelegate::SyncedTabDelegate() = default;
+SyncedTabDelegate::~SyncedTabDelegate() = default;
 
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/synced_window_delegates_getter.cc b/components/sync_sessions/synced_window_delegates_getter.cc
index 9c496f4..ac9f32c 100644
--- a/components/sync_sessions/synced_window_delegates_getter.cc
+++ b/components/sync_sessions/synced_window_delegates_getter.cc
@@ -6,8 +6,8 @@
 
 namespace sync_sessions {
 
-SyncedWindowDelegatesGetter::SyncedWindowDelegatesGetter() {}
+SyncedWindowDelegatesGetter::SyncedWindowDelegatesGetter() = default;
 
-SyncedWindowDelegatesGetter::~SyncedWindowDelegatesGetter() {}
+SyncedWindowDelegatesGetter::~SyncedWindowDelegatesGetter() = default;
 
 }  // namespace sync_sessions
diff --git a/components/sync_sessions/tab_node_pool.cc b/components/sync_sessions/tab_node_pool.cc
index 6e180a0..db03ace 100644
--- a/components/sync_sessions/tab_node_pool.cc
+++ b/components/sync_sessions/tab_node_pool.cc
@@ -27,7 +27,7 @@
 // We start vending tab node IDs at 0.
 const int TabNodePool::kInvalidTabNodeID = -1;
 
-TabNodePool::~TabNodePool() {}
+TabNodePool::~TabNodePool() = default;
 
 void TabNodePool::AddTabNode(int tab_node_id) {
   DCHECK_GT(tab_node_id, kInvalidTabNodeID);
diff --git a/components/sync_sessions/tab_node_pool_unittest.cc b/components/sync_sessions/tab_node_pool_unittest.cc
index b2eb15ca..09c959f5 100644
--- a/components/sync_sessions/tab_node_pool_unittest.cc
+++ b/components/sync_sessions/tab_node_pool_unittest.cc
@@ -28,7 +28,7 @@
 
 class SyncTabNodePoolTest : public testing::Test {
  protected:
-  SyncTabNodePoolTest() {}
+  SyncTabNodePoolTest() = default;
 
   int GetMaxUsedTabNodeId() const { return pool_.GetMaxUsedTabNodeIdForTest(); }
 
diff --git a/components/sync_sessions/test_synced_window_delegates_getter.cc b/components/sync_sessions/test_synced_window_delegates_getter.cc
index b6513c4..67146f0c 100644
--- a/components/sync_sessions/test_synced_window_delegates_getter.cc
+++ b/components/sync_sessions/test_synced_window_delegates_getter.cc
@@ -45,7 +45,7 @@
                                                                    entry.get());
 
   entries_.push_back(std::move(entry));
-  page_language_per_index_.push_back(std::string());
+  page_language_per_index_.emplace_back();
   set_current_entry_index(GetCurrentEntryIndex() + 1);
   notify_cb_.Run(this);
 }
diff --git a/components/sync_user_events/fake_user_event_service.cc b/components/sync_user_events/fake_user_event_service.cc
index 833d7bbb..a68c14b 100644
--- a/components/sync_user_events/fake_user_event_service.cc
+++ b/components/sync_user_events/fake_user_event_service.cc
@@ -11,7 +11,7 @@
 FakeUserEventService::FakeUserEventService()
     : fake_controller_delegate_(syncer::USER_EVENTS) {}
 
-FakeUserEventService::~FakeUserEventService() {}
+FakeUserEventService::~FakeUserEventService() = default;
 
 void FakeUserEventService::RecordUserEvent(
     std::unique_ptr<UserEventSpecifics> specifics) {
diff --git a/components/sync_user_events/no_op_user_event_service.cc b/components/sync_user_events/no_op_user_event_service.cc
index 505d60d..c44d16f 100644
--- a/components/sync_user_events/no_op_user_event_service.cc
+++ b/components/sync_user_events/no_op_user_event_service.cc
@@ -10,9 +10,9 @@
 
 namespace syncer {
 
-NoOpUserEventService::NoOpUserEventService() {}
+NoOpUserEventService::NoOpUserEventService() = default;
 
-NoOpUserEventService::~NoOpUserEventService() {}
+NoOpUserEventService::~NoOpUserEventService() = default;
 
 void NoOpUserEventService::RecordUserEvent(
     std::unique_ptr<UserEventSpecifics> specifics) {}
diff --git a/components/translate/content/android/java/src/org/chromium/components/translate/TranslateTabLayout.java b/components/translate/content/android/java/src/org/chromium/components/translate/TranslateTabLayout.java
index 065e28b7..addb138 100644
--- a/components/translate/content/android/java/src/org/chromium/components/translate/TranslateTabLayout.java
+++ b/components/translate/content/android/java/src/org/chromium/components/translate/TranslateTabLayout.java
@@ -51,7 +51,7 @@
         super(context, attrs);
 
         TypedArray a = context.obtainStyledAttributes(
-                attrs, R.styleable.TabLayout, 0, R.style.Widget_Design_TabLayout);
+                attrs, R.styleable.TabLayout, 0, R.style.Widget_MaterialComponents_TabLayout);
         mTabPaddingStart = mTabPaddingEnd =
                 a.getDimensionPixelSize(R.styleable.TabLayout_tabPadding, 0);
         mTabPaddingStart =
diff --git a/components/variations/service/variations_field_trial_creator.cc b/components/variations/service/variations_field_trial_creator.cc
index e09c293..3463a30 100644
--- a/components/variations/service/variations_field_trial_creator.cc
+++ b/components/variations/service/variations_field_trial_creator.cc
@@ -174,9 +174,6 @@
 }
 
 bool VariationsFieldTrialCreator::SetupFieldTrials(
-    const char* kEnableGpuBenchmarking,
-    const char* kEnableFeatures,
-    const char* kDisableFeatures,
     const std::vector<std::string>& variation_ids,
     const std::vector<base::FeatureList::FeatureOverrideInfo>& extra_overrides,
     std::unique_ptr<const base::FieldTrial::EntropyProvider>
@@ -194,11 +191,6 @@
 
   const base::CommandLine* command_line =
       base::CommandLine::ForCurrentProcess();
-  if (command_line->HasSwitch(switches::kEnableBenchmarking) ||
-      command_line->HasSwitch(kEnableGpuBenchmarking)) {
-    base::FieldTrial::EnableBenchmarking();
-  }
-
   if (command_line->HasSwitch(switches::kForceFieldTrialParams)) {
     bool result = AssociateParamsFromString(
         command_line->GetSwitchValueASCII(switches::kForceFieldTrialParams));
@@ -269,8 +261,8 @@
   }
 
   feature_list->InitializeFromCommandLine(
-      command_line->GetSwitchValueASCII(kEnableFeatures),
-      command_line->GetSwitchValueASCII(kDisableFeatures));
+      command_line->GetSwitchValueASCII(::switches::kEnableFeatures),
+      command_line->GetSwitchValueASCII(::switches::kDisableFeatures));
 
   // This needs to happen here: After the InitializeFromCommandLine() call,
   // because the explicit cmdline --disable-features and --enable-features
diff --git a/components/variations/service/variations_field_trial_creator.h b/components/variations/service/variations_field_trial_creator.h
index 570ffd2..463fac1 100644
--- a/components/variations/service/variations_field_trial_creator.h
+++ b/components/variations/service/variations_field_trial_creator.h
@@ -101,8 +101,6 @@
   // Sets up field trials based on stored variations seed data. Returns whether
   // setup completed successfully.
   //
-  // |kEnableGpuBenchmarking|, |kEnableFeatures|, |kDisableFeatures| are
-  // feature-controlling flags not directly accessible from variations.
   // |variation_ids| allows for forcing ids selected in chrome://flags and/or
   // specified using the command-line flag.
   // |extra_overrides| gives a list of feature overrides that should be applied
@@ -131,9 +129,6 @@
   // take precedence over |extra_overrides|, which takes precedence over the
   // field trials.
   bool SetupFieldTrials(
-      const char* kEnableGpuBenchmarking,
-      const char* kEnableFeatures,
-      const char* kDisableFeatures,
       const std::vector<std::string>& variation_ids,
       const std::vector<base::FeatureList::FeatureOverrideInfo>&
           extra_overrides,
diff --git a/components/variations/service/variations_field_trial_creator_unittest.cc b/components/variations/service/variations_field_trial_creator_unittest.cc
index 3aa1a364..f7c0fd1 100644
--- a/components/variations/service/variations_field_trial_creator_unittest.cc
+++ b/components/variations/service/variations_field_trial_creator_unittest.cc
@@ -305,10 +305,11 @@
   bool SetupFieldTrials(bool extend_variations_safe_mode = true) {
     TestPlatformFieldTrials platform_field_trials;
     return VariationsFieldTrialCreator::SetupFieldTrials(
-        "", "", "", std::vector<std::string>(),
-        std::vector<base::FeatureList::FeatureOverrideInfo>(), nullptr,
-        std::make_unique<base::FeatureList>(), metrics_state_manager_.get(),
-        &platform_field_trials, safe_seed_manager_, absl::nullopt,
+        /*variation_ids=*/std::vector<std::string>(),
+        std::vector<base::FeatureList::FeatureOverrideInfo>(),
+        /*low_entropy_provider=*/nullptr, std::make_unique<base::FeatureList>(),
+        metrics_state_manager_.get(), &platform_field_trials,
+        safe_seed_manager_, /*low_entropy_source_value=*/absl::nullopt,
         extend_variations_safe_mode);
   }
 
@@ -810,10 +811,11 @@
   // |initial_seed| included the country code for India, this study should be
   // active.
   EXPECT_TRUE(field_trial_creator.SetupFieldTrials(
-      "", "", "", std::vector<std::string>(),
-      std::vector<base::FeatureList::FeatureOverrideInfo>(), nullptr,
-      std::make_unique<base::FeatureList>(), metrics_state_manager.get(),
-      &platform_field_trials, &safe_seed_manager, absl::nullopt));
+      /*variation_ids=*/std::vector<std::string>(),
+      std::vector<base::FeatureList::FeatureOverrideInfo>(),
+      /*low_entropy_provider=*/nullptr, std::make_unique<base::FeatureList>(),
+      metrics_state_manager.get(), &platform_field_trials, &safe_seed_manager,
+      /*low_entropy_source_value=*/absl::nullopt));
 
   EXPECT_EQ(kTestSeedExperimentName,
             base::FieldTrialList::FindFullName(kTestSeedStudyName));
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc
index 5bb1e9cd..8d507809 100644
--- a/components/variations/service/variations_service.cc
+++ b/components/variations/service/variations_service.cc
@@ -960,19 +960,16 @@
 }
 
 bool VariationsService::SetupFieldTrials(
-    const char* kEnableGpuBenchmarking,
-    const char* kEnableFeatures,
-    const char* kDisableFeatures,
     const std::vector<std::string>& variation_ids,
     const std::vector<base::FeatureList::FeatureOverrideInfo>& extra_overrides,
     std::unique_ptr<base::FeatureList> feature_list,
     variations::PlatformFieldTrials* platform_field_trials,
     bool extend_variations_safe_mode) {
   return field_trial_creator_.SetupFieldTrials(
-      kEnableGpuBenchmarking, kEnableFeatures, kDisableFeatures, variation_ids,
-      extra_overrides, CreateLowEntropyProvider(), std::move(feature_list),
-      state_manager_, platform_field_trials, &safe_seed_manager_,
-      state_manager_->GetLowEntropySource(), extend_variations_safe_mode);
+      variation_ids, extra_overrides, CreateLowEntropyProvider(),
+      std::move(feature_list), state_manager_, platform_field_trials,
+      &safe_seed_manager_, state_manager_->GetLowEntropySource(),
+      extend_variations_safe_mode);
 }
 
 void VariationsService::OverrideCachedUIStrings() {
diff --git a/components/variations/service/variations_service.h b/components/variations/service/variations_service.h
index 04805fa..85926c9 100644
--- a/components/variations/service/variations_service.h
+++ b/components/variations/service/variations_service.h
@@ -190,9 +190,6 @@
   // Wrapper around VariationsFieldTrialCreator::SetupFieldTrials().
   // TODO(crbug/1245646): Remove |extend_variations_safe_mode| param.
   bool SetupFieldTrials(
-      const char* kEnableGpuBenchmarking,
-      const char* kEnableFeatures,
-      const char* kDisableFeatures,
       const std::vector<std::string>& variation_ids,
       const std::vector<base::FeatureList::FeatureOverrideInfo>&
           extra_overrides,
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc
index f4c4eaf..a43be2cc 100644
--- a/components/viz/service/gl/gpu_service_impl.cc
+++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -1080,6 +1080,9 @@
   }
   DVLOG(1) << "GPU: GPU has switched";
 
+  if (watchdog_thread_)
+    watchdog_thread_->ReportProgress();
+
   if (!in_host_process()) {
     ui::GpuSwitchingManager::GetInstance()->NotifyGpuSwitched(
         active_gpu_heuristic);
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 1cddeb7..51a7f04 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -357,6 +357,8 @@
     "aggregation_service/aggregation_service_key_fetcher.cc",
     "aggregation_service/aggregation_service_key_fetcher.h",
     "aggregation_service/aggregation_service_key_storage.h",
+    "aggregation_service/aggregation_service_network_fetcher_impl.cc",
+    "aggregation_service/aggregation_service_network_fetcher_impl.h",
     "aggregation_service/aggregation_service_storage_sql.cc",
     "aggregation_service/aggregation_service_storage_sql.h",
     "aggregation_service/public_key.cc",
diff --git a/content/browser/aggregation_service/aggregation_service_key_fetcher.cc b/content/browser/aggregation_service/aggregation_service_key_fetcher.cc
index 48ff379..d4b5ae33 100644
--- a/content/browser/aggregation_service/aggregation_service_key_fetcher.cc
+++ b/content/browser/aggregation_service/aggregation_service_key_fetcher.cc
@@ -4,10 +4,13 @@
 
 #include "content/browser/aggregation_service/aggregation_service_key_fetcher.h"
 
+#include <memory>
 #include <utility>
+#include <vector>
 
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/containers/circular_deque.h"
 #include "base/rand_util.h"
 #include "content/browser/aggregation_service/aggregatable_report_manager.h"
 #include "content/browser/aggregation_service/aggregation_service_key_storage.h"
@@ -18,8 +21,9 @@
 namespace content {
 
 AggregationServiceKeyFetcher::AggregationServiceKeyFetcher(
-    AggregatableReportManager* manager)
-    : manager_(manager) {}
+    AggregatableReportManager* manager,
+    std::unique_ptr<NetworkFetcher> network_fetcher)
+    : manager_(manager), network_fetcher_(std::move(network_fetcher)) {}
 
 AggregationServiceKeyFetcher::~AggregationServiceKeyFetcher() = default;
 
@@ -31,31 +35,104 @@
     return;
   }
 
+  base::circular_deque<FetchCallback>& pending_callbacks =
+      origin_callbacks_[origin];
+  bool in_progress = !pending_callbacks.empty();
+  pending_callbacks.push_back(std::move(callback));
+
+  // If there is already a fetch request in progress, just enqueue the
+  // callback and return.
+  if (in_progress)
+    return;
+
+  // First we check if we already have keys stored.
+  // TODO(crbug.com/1223488): Pass origin by value and move after C++17.
   manager_->GetKeyStorage()
       .AsyncCall(&AggregationServiceKeyStorage::GetPublicKeys)
       .WithArgs(origin)
       .Then(base::BindOnce(
           &AggregationServiceKeyFetcher::OnPublicKeysReceivedFromStorage,
-          weak_factory_.GetWeakPtr(), std::move(callback)));
+          weak_factory_.GetWeakPtr(), origin));
 }
 
 void AggregationServiceKeyFetcher::OnPublicKeysReceivedFromStorage(
-    FetchCallback callback,
-    PublicKeysForOrigin keys_for_origin) {
-  if (keys_for_origin.keys.empty()) {
-    // TODO(crbug.com/1217823): Fetch public keys from the network.
-
-    std::move(callback).Run(absl::nullopt,
-                            PublicKeyFetchStatus::kPublicKeyFetchFailed);
+    const url::Origin& origin,
+    std::vector<PublicKey> keys) {
+  if (keys.empty()) {
+    // Fetch keys from the network if not found in the storage.
+    FetchPublicKeysFromNetwork(origin);
     return;
   }
 
-  // Each report should randomly select a key. This ensures that the set of
-  // reports a client sends are not a subset of the reports identified by any
-  // one key.
-  uint64_t key_index = base::RandGenerator(keys_for_origin.keys.size());
-  std::move(callback).Run(std::move(keys_for_origin.keys[key_index]),
-                          PublicKeyFetchStatus::kOk);
+  RunCallbacksForOrigin(origin, keys);
+}
+
+void AggregationServiceKeyFetcher::FetchPublicKeysFromNetwork(
+    const url::Origin& origin) {
+  if (!network_fetcher_) {
+    // Return error if fetching from network is not enabled.
+    RunCallbacksForOrigin(origin, /*keys=*/{});
+    return;
+  }
+
+  // Unretained is safe because the network fetcher is owned by `this` and will
+  // be deleted before `this`.
+  network_fetcher_->FetchPublicKeys(
+      origin,
+      base::BindOnce(
+          &AggregationServiceKeyFetcher::OnPublicKeysReceivedFromNetwork,
+          base::Unretained(this), origin));
+}
+
+void AggregationServiceKeyFetcher::OnPublicKeysReceivedFromNetwork(
+    const url::Origin& origin,
+    absl::optional<PublicKeyset> keyset) {
+  if (!keyset.has_value() || keyset->expiry_time.is_null()) {
+    // `keyset` will be absl::nullopt if an error occurred and `expiry_time`
+    // will be null if the freshness lifetime was zero. In these cases, we will
+    // still update the keys for `origin`, i,e. clear them.
+    manager_->GetKeyStorage()
+        .AsyncCall(&AggregationServiceKeyStorage::ClearPublicKeys)
+        .WithArgs(origin);
+  } else {
+    // Store public keys fetched from network to storage, the old keys will be
+    // deleted from storage.
+    manager_->GetKeyStorage()
+        .AsyncCall(&AggregationServiceKeyStorage::SetPublicKeys)
+        .WithArgs(origin, keyset.value());
+  }
+
+  RunCallbacksForOrigin(
+      origin, keyset.has_value() ? keyset->keys : std::vector<PublicKey>());
+}
+
+void AggregationServiceKeyFetcher::RunCallbacksForOrigin(
+    const url::Origin& origin,
+    const std::vector<PublicKey>& keys) {
+  auto iter = origin_callbacks_.find(origin);
+  DCHECK(iter != origin_callbacks_.end());
+
+  base::circular_deque<FetchCallback> pending_callbacks =
+      std::move(iter->second);
+  DCHECK(!pending_callbacks.empty());
+
+  origin_callbacks_.erase(iter);
+
+  if (keys.empty()) {
+    // Return error, don't refetch to avoid infinite loop.
+    for (auto& callback : pending_callbacks) {
+      std::move(callback).Run(absl::nullopt,
+                              PublicKeyFetchStatus::kPublicKeyFetchFailed);
+    }
+  } else {
+    for (auto& callback : pending_callbacks) {
+      // Each report should randomly select a key. This ensures that the set of
+      // reports a client sends are not a subset of the reports identified by
+      // any one key.
+      uint64_t key_index = base::RandGenerator(keys.size());
+      std::move(callback).Run(keys[key_index], PublicKeyFetchStatus::kOk);
+    }
+  }
 }
 
 }  // namespace content
diff --git a/content/browser/aggregation_service/aggregation_service_key_fetcher.h b/content/browser/aggregation_service/aggregation_service_key_fetcher.h
index 36b6499..2f8538d 100644
--- a/content/browser/aggregation_service/aggregation_service_key_fetcher.h
+++ b/content/browser/aggregation_service/aggregation_service_key_fetcher.h
@@ -5,7 +5,12 @@
 #ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_KEY_FETCHER_H_
 #define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_KEY_FETCHER_H_
 
+#include <memory>
+#include <vector>
+
 #include "base/callback_forward.h"
+#include "base/containers/circular_deque.h"
+#include "base/containers/flat_map.h"
 #include "base/memory/weak_ptr.h"
 #include "content/browser/aggregation_service/public_key.h"
 #include "content/common/content_export.h"
@@ -23,6 +28,21 @@
 // assembler.
 class CONTENT_EXPORT AggregationServiceKeyFetcher {
  public:
+  // This class is responsible for fetching public keys from helper servers over
+  // the network.
+  class NetworkFetcher {
+   public:
+    virtual ~NetworkFetcher() = default;
+
+    using NetworkFetchCallback =
+        base::OnceCallback<void(absl::optional<PublicKeyset>)>;
+
+    // Fetch public keys for `origin` from the helper servers. Returns
+    // absl::nullopt in case of network or parsing error.
+    virtual void FetchPublicKeys(const url::Origin& origin,
+                                 NetworkFetchCallback callback) = 0;
+  };
+
   enum class PublicKeyFetchStatus {
     // TODO(crbug.com/1217823): Propagate up more granular errors.
     kOk = 0,
@@ -34,7 +54,8 @@
   using FetchCallback =
       base::OnceCallback<void(absl::optional<PublicKey>, PublicKeyFetchStatus)>;
 
-  explicit AggregationServiceKeyFetcher(AggregatableReportManager* manager);
+  AggregationServiceKeyFetcher(AggregatableReportManager* manager,
+                               std::unique_ptr<NetworkFetcher> network_fetcher);
   AggregationServiceKeyFetcher(const AggregationServiceKeyFetcher& other) =
       delete;
   AggregationServiceKeyFetcher& operator=(
@@ -59,12 +80,36 @@
 
  private:
   // Called when public keys are received from the storage.
-  void OnPublicKeysReceivedFromStorage(FetchCallback callback,
-                                       PublicKeysForOrigin keys_for_origin);
+  void OnPublicKeysReceivedFromStorage(const url::Origin& origin,
+                                       std::vector<PublicKey> keys);
+
+  // Keys are fetched from the network if they are not found in storage.
+  void FetchPublicKeysFromNetwork(const url::Origin& origin);
+
+  // Called when public keys are received from the network fetcher.
+  void OnPublicKeysReceivedFromNetwork(const url::Origin& origin,
+                                       absl::optional<PublicKeyset> keyset);
+
+  // Runs callbacks for pending requests for `origin` with the public keys
+  // received from the network or storage. Any keys specified must be currently
+  // valid.
+  void RunCallbacksForOrigin(const url::Origin& origin,
+                             const std::vector<PublicKey>& keys);
 
   // Using a raw pointer is safe because `manager_` is guaranteed to outlive
   // `this`.
   AggregatableReportManager* manager_;
+
+  // Map of all origins that are currently waiting for the public keys, and
+  // their associated fetch callbacks. Used to cache ongoing requests to the
+  // storage or network to prevent looking up the same key multiple times at
+  // once.
+  base::flat_map<url::Origin, base::circular_deque<FetchCallback>>
+      origin_callbacks_;
+
+  // Responsible for issuing requests to network for fetching public keys.
+  std::unique_ptr<NetworkFetcher> network_fetcher_;
+
   base::WeakPtrFactory<AggregationServiceKeyFetcher> weak_factory_{this};
 };
 
diff --git a/content/browser/aggregation_service/aggregation_service_key_fetcher_unittest.cc b/content/browser/aggregation_service/aggregation_service_key_fetcher_unittest.cc
index dfac09b..8185ddd 100644
--- a/content/browser/aggregation_service/aggregation_service_key_fetcher_unittest.cc
+++ b/content/browser/aggregation_service/aggregation_service_key_fetcher_unittest.cc
@@ -5,8 +5,11 @@
 #include "content/browser/aggregation_service/aggregation_service_key_fetcher.h"
 
 #include <memory>
+#include <utility>
+#include <vector>
 
-#include "base/callback_helpers.h"
+#include "base/callback.h"
+#include "base/containers/flat_map.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "base/test/task_environment.h"
@@ -15,23 +18,58 @@
 #include "content/browser/aggregation_service/aggregation_service_test_utils.h"
 #include "content/browser/aggregation_service/public_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
 namespace content {
 
+namespace {
+
+// NetworkFetcher that manages the public keys in memory.
+class MockNetworkFetcher : public AggregationServiceKeyFetcher::NetworkFetcher {
+ public:
+  // AggregationServiceKeyFetcher::NetworkFetcher:
+  void FetchPublicKeys(const url::Origin& origin,
+                       NetworkFetchCallback callback) override {
+    auto it = public_keys_map_.find(origin);
+    if (it != public_keys_map_.end()) {
+      std::move(callback).Run(it->second);
+    } else {
+      std::move(callback).Run(absl::nullopt);
+    }
+
+    ++num_fetches_;
+  }
+
+  void SetPublicKeys(url::Origin origin, PublicKeyset keyset) {
+    public_keys_map_.insert_or_assign(std::move(origin), std::move(keyset));
+  }
+
+  int num_fetches() const { return num_fetches_; }
+
+ private:
+  base::flat_map<url::Origin, PublicKeyset> public_keys_map_;
+  int num_fetches_ = 0;
+};
+
+}  // namespace
+
 class AggregationServiceKeyFetcherTest : public testing::Test {
  public:
   AggregationServiceKeyFetcherTest()
       : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
-        manager_(task_environment_.GetMockClock()),
-        fetcher_(std::make_unique<AggregationServiceKeyFetcher>(&manager_)) {}
+        manager_(task_environment_.GetMockClock()) {
+    auto network_fetcher = std::make_unique<MockNetworkFetcher>();
+    network_fetcher_ = network_fetcher.get();
+    fetcher_ = std::make_unique<AggregationServiceKeyFetcher>(
+        &manager_, std::move(network_fetcher));
+  }
 
-  void SetPublicKeys(const PublicKeysForOrigin& keys) {
+  void SetPublicKeysInStorage(const url::Origin& origin, PublicKeyset keyset) {
     manager_.GetKeyStorage()
         .AsyncCall(&AggregationServiceKeyStorage::SetPublicKeys)
-        .WithArgs(keys, /*fetch_time=*/clock().Now(),
-                  /*expiry_time=*/base::Time::Max());
+        .WithArgs(origin, std::move(keyset));
   }
 
   void ExpectPublicKeyFetched(const url::Origin& origin,
@@ -45,8 +83,9 @@
               EXPECT_TRUE(key.has_value());
               EXPECT_TRUE(aggregation_service::PublicKeysEqual({expected_key},
                                                                {key.value()}));
-              EXPECT_EQ(AggregationServiceKeyFetcher::PublicKeyFetchStatus::kOk,
-                        status);
+              EXPECT_EQ(
+                  status,
+                  AggregationServiceKeyFetcher::PublicKeyFetchStatus::kOk);
               run_loop.Quit();
             }));
     run_loop.Run();
@@ -62,28 +101,46 @@
             [&](absl::optional<PublicKey> key,
                 AggregationServiceKeyFetcher::PublicKeyFetchStatus status) {
               EXPECT_FALSE(key.has_value());
-              EXPECT_EQ(expected_status, status);
+              EXPECT_EQ(status, expected_status);
+              run_loop.Quit();
+            }));
+    run_loop.Run();
+  }
+
+  void ExpectPublicKeysInStorage(const url::Origin& origin,
+                                 const std::vector<PublicKey>& expected_keys) {
+    base::RunLoop run_loop;
+    manager_.GetKeyStorage()
+        .AsyncCall(&AggregationServiceKeyStorage::GetPublicKeys)
+        .WithArgs(origin)
+        .Then(
+            base::BindLambdaForTesting([&](std::vector<PublicKey> actual_keys) {
+              EXPECT_TRUE(aggregation_service::PublicKeysEqual(expected_keys,
+                                                               actual_keys));
               run_loop.Quit();
             }));
     run_loop.Run();
   }
 
  protected:
+  const base::Clock& clock() const { return *task_environment_.GetMockClock(); }
+
   base::test::TaskEnvironment task_environment_;
   TestAggregatableReportManager manager_;
   std::unique_ptr<AggregationServiceKeyFetcher> fetcher_;
-
- private:
-  const base::Clock& clock() { return *task_environment_.GetMockClock(); }
+  MockNetworkFetcher* network_fetcher_;
 };
 
-TEST_F(AggregationServiceKeyFetcherTest, GetPublicKeys_Succeed) {
+TEST_F(AggregationServiceKeyFetcherTest, GetPublicKeysFromStorage_Succeed) {
   url::Origin origin = url::Origin::Create(GURL("https://a.com"));
   PublicKey expected_key(/*id=*/"abcd", /*key=*/kABCD1234AsBytes);
-  PublicKeysForOrigin origin_keys(origin, {expected_key});
 
-  SetPublicKeys(origin_keys);
+  SetPublicKeysInStorage(
+      origin,
+      PublicKeyset(/*keys=*/{expected_key}, /*fetch_time=*/clock().Now(),
+                   /*expiry_time=*/base::Time::Max()));
   ExpectPublicKeyFetched(origin, expected_key);
+  EXPECT_EQ(network_fetcher_->num_fetches(), 0);
 }
 
 TEST_F(AggregationServiceKeyFetcherTest,
@@ -104,9 +161,128 @@
 TEST_F(AggregationServiceKeyFetcherTest,
        GetPublicKeysWithNoKeysForOrigin_Failed) {
   url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  SetPublicKeysInStorage(
+      origin,
+      PublicKeyset(
+          /*keys=*/{PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes)},
+          /*fetch_time=*/clock().Now(), /*expiry_time=*/base::Time::Max()));
+
+  url::Origin other_origin = url::Origin::Create(GURL("https://b.com"));
+  ExpectKeyFetchFailure(other_origin,
+                        AggregationServiceKeyFetcher::PublicKeyFetchStatus::
+                            kPublicKeyFetchFailed);
+}
+
+TEST_F(AggregationServiceKeyFetcherTest, FetchPublicKeysFromNetwork_Succeed) {
+  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  PublicKey expected_key(/*id=*/"abcd", /*key=*/kABCD1234AsBytes);
+
+  network_fetcher_->SetPublicKeys(
+      origin, PublicKeyset(/*keys=*/{expected_key},
+                           /*fetch_time=*/clock().Now(),
+                           /*expiry_time=*/base::Time::Max()));
+  ExpectPublicKeyFetched(origin, expected_key);
+
+  // Verify that the fetched public keys are stored to storage.
+  ExpectPublicKeysInStorage(origin, /*expected_keys=*/{expected_key});
+}
+
+TEST_F(AggregationServiceKeyFetcherTest,
+       FetchPublicKeysFromNetworkNoStore_NotStored) {
+  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  PublicKey expected_key(/*id=*/"abcd", /*key=*/kABCD1234AsBytes);
+
+  network_fetcher_->SetPublicKeys(origin,
+                                  PublicKeyset(/*keys=*/{expected_key},
+                                               /*fetch_time=*/clock().Now(),
+                                               /*expiry_time=*/base::Time()));
+  ExpectPublicKeyFetched(origin, expected_key);
+
+  // Verify that the fetched public keys are not stored to storage.
+  ExpectPublicKeysInStorage(origin, /*expected_keys=*/{});
+}
+
+TEST_F(AggregationServiceKeyFetcherTest,
+       FetchPublicKeysFromNetworkError_StorageCleared) {
+  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  base::Time now = clock().Now();
+
+  PublicKey key(/*id=*/"abcd", /*key=*/kABCD1234AsBytes);
+  SetPublicKeysInStorage(
+      origin, PublicKeyset(/*keys=*/{key}, /*fetch_time=*/now,
+                           /*expiry_time=*/now + base::TimeDelta::FromDays(1)));
+
+  task_environment_.FastForwardBy(base::TimeDelta::FromDays(2));
+
   ExpectKeyFetchFailure(origin,
                         AggregationServiceKeyFetcher::PublicKeyFetchStatus::
                             kPublicKeyFetchFailed);
+
+  // Verify that the public keys in storage are cleared.
+  ExpectPublicKeysInStorage(origin, /*expected_keys=*/{});
+}
+
+TEST_F(AggregationServiceKeyFetcherTest,
+       SimultaneousFetches_NoDuplicateNetworkRequest) {
+  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  PublicKey expected_key(/*id=*/"abcd", /*key=*/kABCD1234AsBytes);
+
+  network_fetcher_->SetPublicKeys(
+      origin, PublicKeyset(/*keys=*/{expected_key},
+                           /*fetch_time=*/clock().Now(),
+                           /*expiry_time=*/base::Time::Max()));
+  ExpectPublicKeyFetched(origin, expected_key);
+
+  base::RunLoop run_loop;
+  int num_callbacks = 0;
+  for (int i = 0; i < 10; i++) {
+    fetcher_->GetPublicKey(
+        origin,
+        base::BindLambdaForTesting(
+            [&](absl::optional<PublicKey> key,
+                AggregationServiceKeyFetcher::PublicKeyFetchStatus status) {
+              EXPECT_TRUE(key.has_value());
+              EXPECT_TRUE(aggregation_service::PublicKeysEqual({expected_key},
+                                                               {key.value()}));
+              EXPECT_EQ(
+                  status,
+                  AggregationServiceKeyFetcher::PublicKeyFetchStatus::kOk);
+              if (++num_callbacks == 10)
+                run_loop.Quit();
+            }));
+  }
+
+  run_loop.Run();
+
+  EXPECT_EQ(network_fetcher_->num_fetches(), 1);
+}
+
+TEST_F(AggregationServiceKeyFetcherTest,
+       SimultaneousFetchesInvalidKeysFromNetwork_NoDuplicateNetworkRequest) {
+  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+
+  // Keys not set in network fetcher, will return empty keys.
+
+  base::RunLoop run_loop;
+  int num_callbacks = 0;
+  for (int i = 0; i < 10; i++) {
+    fetcher_->GetPublicKey(
+        origin,
+        base::BindLambdaForTesting(
+            [&](absl::optional<PublicKey> key,
+                AggregationServiceKeyFetcher::PublicKeyFetchStatus status) {
+              EXPECT_FALSE(key.has_value());
+              EXPECT_EQ(status,
+                        AggregationServiceKeyFetcher::PublicKeyFetchStatus::
+                            kPublicKeyFetchFailed);
+              if (++num_callbacks == 10)
+                run_loop.Quit();
+            }));
+  }
+
+  run_loop.Run();
+
+  EXPECT_EQ(network_fetcher_->num_fetches(), 1);
 }
 
 }  // namespace content
diff --git a/content/browser/aggregation_service/aggregation_service_key_storage.h b/content/browser/aggregation_service/aggregation_service_key_storage.h
index f8dcd9b4e..bdaa5df 100644
--- a/content/browser/aggregation_service/aggregation_service_key_storage.h
+++ b/content/browser/aggregation_service/aggregation_service_key_storage.h
@@ -5,6 +5,8 @@
 #ifndef CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_KEY_STORAGE_H_
 #define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_KEY_STORAGE_H_
 
+#include <vector>
+
 #include "content/common/content_export.h"
 
 namespace base {
@@ -17,7 +19,8 @@
 
 namespace content {
 
-struct PublicKeysForOrigin;
+struct PublicKey;
+struct PublicKeyset;
 
 // This class provides an interface for persisting helper server public keys
 // and performing queries on it.
@@ -27,12 +30,11 @@
 
   // Returns the public keys for `origin` that are currently valid. The returned
   // value should not be stored for future operations as it may expire soon.
-  virtual PublicKeysForOrigin GetPublicKeys(const url::Origin& origin) = 0;
+  virtual std::vector<PublicKey> GetPublicKeys(const url::Origin& origin) = 0;
 
   // Sets the public keys for `origin`.
-  virtual void SetPublicKeys(const PublicKeysForOrigin& keys,
-                             const base::Time& fetch_time,
-                             const base::Time& expiry_time) = 0;
+  virtual void SetPublicKeys(const url::Origin& origin,
+                             const PublicKeyset& keyset) = 0;
 
   // Clears the stored public keys for `origin`.
   virtual void ClearPublicKeys(const url::Origin& origin) = 0;
diff --git a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc
new file mode 100644
index 0000000..31510a4
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc
@@ -0,0 +1,215 @@
+// Copyright 2021 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/aggregation_service/aggregation_service_network_fetcher_impl.h"
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/time/clock.h"
+#include "base/time/time.h"
+#include "content/browser/aggregation_service/public_key_parsing_utils.h"
+#include "content/public/browser/storage_partition.h"
+#include "net/base/load_flags.h"
+#include "net/http/http_response_headers.h"
+#include "net/traffic_annotation/network_traffic_annotation.h"
+#include "services/data_decoder/public/cpp/data_decoder.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+#include "url/third_party/mozilla/url_parse.h"
+#include "url/url_canon.h"
+
+namespace content {
+
+namespace {
+
+GURL GetPublicKeyUrl(const url::Origin& origin) {
+  url::Replacements<char> replacements;
+  static constexpr char kEndpointPath[] =
+      ".well-known/aggregation-service/keys.json";
+  replacements.SetPath(kEndpointPath, url::Component(0, strlen(kEndpointPath)));
+  return origin.GetURL().ReplaceComponents(replacements);
+}
+
+}  // namespace
+
+AggregationServiceNetworkFetcherImpl::AggregationServiceNetworkFetcherImpl(
+    const base::Clock* clock,
+    StoragePartition* storage_partition)
+    : clock_(*clock), storage_partition_(*storage_partition) {}
+
+AggregationServiceNetworkFetcherImpl::~AggregationServiceNetworkFetcherImpl() =
+    default;
+
+void AggregationServiceNetworkFetcherImpl::FetchPublicKeys(
+    const url::Origin& origin,
+    NetworkFetchCallback callback) {
+  // The browser process URLLoaderFactory is not created by default, so don't
+  // create it until it is directly needed.
+  if (!url_loader_factory_) {
+    url_loader_factory_ =
+        storage_partition_.GetURLLoaderFactoryForBrowserProcess();
+  }
+
+  GURL public_key_url = GetPublicKeyUrl(origin);
+
+  auto resource_request = std::make_unique<network::ResourceRequest>();
+  resource_request->url = public_key_url;
+  resource_request->method = net::HttpRequestHeaders::kGetMethod;
+  resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
+  // No cache read, always download from the network.
+  resource_request->load_flags =
+      net::LOAD_DISABLE_CACHE | net::LOAD_BYPASS_CACHE;
+
+  // TODO(crbug.com/1238343): Update the "policy" field in the traffic
+  // annotation when a setting to disable the API is properly
+  // surfaced/implemented.
+  net::NetworkTrafficAnnotationTag traffic_annotation =
+      net::DefineNetworkTrafficAnnotation("aggregation_service_helper_keys", R"(
+        semantics {
+          sender: "Aggregation Service"
+          description:
+            "Downloads public keys for helper servers requested by APIs that "
+            "rely on private, secure aggregation (e.g. Attribution Reporting "
+            "API, see https://github.com/WICG/conversion-measurement-api). "
+            "Keys are requested prior to aggregate reports being sent and are "
+            "used to encrypt payloads for the helper servers."
+          trigger:
+            "When an aggregatable report is about to be assembled and sent."
+          data:
+            "JSON data comprising public key information."
+          destination: OTHER
+        }
+        policy {
+            cookies_allowed: NO
+            setting:
+              "This feature cannot be disabled by settings."
+            policy_exception_justification: "Not implemented yet."
+        })");
+
+  auto simple_url_loader = network::SimpleURLLoader::Create(
+      std::move(resource_request), traffic_annotation);
+  network::SimpleURLLoader* simple_url_loader_ptr = simple_url_loader.get();
+
+  auto it = loaders_in_progress_.insert(loaders_in_progress_.begin(),
+                                        std::move(simple_url_loader));
+  simple_url_loader_ptr->SetTimeoutDuration(base::TimeDelta::FromSeconds(30));
+
+  const int kMaxRetries = 1;
+
+  // Retry on a network change. A network change during DNS resolution
+  // results in a DNS error rather than a network change error, so retry in
+  // those cases as well.
+  int retry_mode = network::SimpleURLLoader::RETRY_ON_NETWORK_CHANGE |
+                   network::SimpleURLLoader::RETRY_ON_NAME_NOT_RESOLVED;
+  simple_url_loader_ptr->SetRetryOptions(kMaxRetries, retry_mode);
+
+  // This is an arbitrary choice and should generally be large enough to contain
+  // keys encoded in the format.
+  const int kMaxJsonSize = 1000000;  // 1Mb
+
+  // Unretained is safe because the URLLoader is owned by `this` and will be
+  // deleted before `this`.
+  simple_url_loader_ptr->DownloadToString(
+      url_loader_factory_.get(),
+      base::BindOnce(
+          &AggregationServiceNetworkFetcherImpl::OnSimpleLoaderComplete,
+          base::Unretained(this), std::move(it), origin, std::move(callback)),
+      kMaxJsonSize);
+}
+
+void AggregationServiceNetworkFetcherImpl::SetURLLoaderFactoryForTesting(
+    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) {
+  url_loader_factory_ = url_loader_factory;
+}
+
+void AggregationServiceNetworkFetcherImpl::OnSimpleLoaderComplete(
+    UrlLoaderList::iterator it,
+    const url::Origin& origin,
+    NetworkFetchCallback callback,
+    std::unique_ptr<std::string> response_body) {
+  std::unique_ptr<network::SimpleURLLoader> loader = std::move(*it);
+  loaders_in_progress_.erase(it);
+
+  if (!response_body) {
+    OnError(origin, std::move(callback), FetchError::kDownload,
+            /*error_msg=*/"Public key network request failed.");
+    return;
+  }
+
+  base::Time response_time;
+  // `expiry_time` will be null if the freshness lifetime is zero.
+  base::Time expiry_time;
+  if (const network::mojom::URLResponseHead* response_info =
+          loader->ResponseInfo()) {
+    response_time = response_info->response_time.is_null()
+                        ? clock_.Now()
+                        : response_info->response_time;
+
+    if (const net::HttpResponseHeaders* headers =
+            response_info->headers.get()) {
+      base::TimeDelta freshness =
+          headers->GetFreshnessLifetimes(response_time).freshness;
+      if (!freshness.is_zero())
+        expiry_time = response_time + freshness;
+    }
+  } else {
+    response_time = clock_.Now();
+  }
+
+  // Since DataDecoder parses untrusted data in a separate process if necessary,
+  // we obey the rule of 2.
+  data_decoder::DataDecoder::ParseJsonIsolated(
+      *response_body,
+      base::BindOnce(&AggregationServiceNetworkFetcherImpl::OnJsonParse,
+                     weak_factory_.GetWeakPtr(), origin, std::move(callback),
+                     std::move(response_time), std::move(expiry_time)));
+
+  // TODO(crbug.com/1232599): Add performance metrics for key fetching.
+}
+
+void AggregationServiceNetworkFetcherImpl::OnJsonParse(
+    const url::Origin& origin,
+    NetworkFetchCallback callback,
+    base::Time fetch_time,
+    base::Time expiry_time,
+    data_decoder::DataDecoder::ValueOrError result) {
+  if (!result.value) {
+    OnError(origin, std::move(callback), FetchError::kJsonParse, *result.error);
+    return;
+  }
+
+  std::vector<PublicKey> keys =
+      aggregation_service::GetPublicKeys(result.value.value());
+  if (keys.empty()) {
+    OnError(origin, std::move(callback), FetchError::kJsonParse,
+            /*error_msg=*/"Public key parsing failed");
+    return;
+  }
+
+  std::move(callback).Run(PublicKeyset(std::move(keys), std::move(fetch_time),
+                                       std::move(expiry_time)));
+}
+
+void AggregationServiceNetworkFetcherImpl::OnError(
+    const url::Origin& origin,
+    NetworkFetchCallback callback,
+    FetchError error,
+    const std::string& error_msg) {
+  // TODO(crbug.com/1232601): Look into better backoff logic for fetching and
+  // parsing error.
+
+  std::move(callback).Run(absl::nullopt);
+}
+
+}  // namespace content
diff --git a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h
new file mode 100644
index 0000000..377b32e7
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl.h
@@ -0,0 +1,101 @@
+// Copyright 2021 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_AGGREGATION_SERVICE_AGGREGATION_SERVICE_NETWORK_FETCHER_IMPL_H_
+#define CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_NETWORK_FETCHER_IMPL_H_
+
+#include <list>
+#include <memory>
+#include <string>
+
+#include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "content/browser/aggregation_service/aggregation_service_key_fetcher.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "content/common/content_export.h"
+#include "services/data_decoder/public/cpp/data_decoder.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
+
+namespace base {
+class Clock;
+class Time;
+}  // namespace base
+
+namespace url {
+class Origin;
+}  // namespace url
+
+namespace content {
+
+class StoragePartition;
+
+// This class fetches a JSON formatted response from a helper server and uses a
+// sandboxed utility process to parse it to a PublicKey array.
+class CONTENT_EXPORT AggregationServiceNetworkFetcherImpl
+    : public AggregationServiceKeyFetcher::NetworkFetcher {
+ public:
+  // `clock` and `storage_partition` must be non-null pointers that are valid as
+  // long as this object.
+  AggregationServiceNetworkFetcherImpl(const base::Clock* clock,
+                                       StoragePartition* storage_partition);
+  AggregationServiceNetworkFetcherImpl(
+      const AggregationServiceNetworkFetcherImpl&) = delete;
+  AggregationServiceNetworkFetcherImpl& operator=(
+      const AggregationServiceNetworkFetcherImpl&) = delete;
+  ~AggregationServiceNetworkFetcherImpl() override;
+
+  void FetchPublicKeys(const url::Origin& origin,
+                       NetworkFetchCallback callback) override;
+
+  // Tests inject a TestURLLoaderFactory so they can mock the network response.
+  void SetURLLoaderFactoryForTesting(
+      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);
+
+ private:
+  enum class FetchError {
+    kDownload = 0,
+    kJsonParse = 1,
+    kMaxValue = kJsonParse,
+  };
+
+  // This is a std::list so that iterators remain valid during modifications.
+  using UrlLoaderList = std::list<std::unique_ptr<network::SimpleURLLoader>>;
+
+  // Invoked from SimpleURLLoader after download is complete.
+  void OnSimpleLoaderComplete(UrlLoaderList::iterator it,
+                              const url::Origin& origin,
+                              NetworkFetchCallback callback,
+                              std::unique_ptr<std::string> response_body);
+
+  // Callback for DataDecoder. `expiry_time` will be null if the freshness
+  // lifetime is zero.
+  void OnJsonParse(const url::Origin& origin,
+                   NetworkFetchCallback callback,
+                   base::Time fetch_time,
+                   base::Time expiry_time,
+                   data_decoder::DataDecoder::ValueOrError result);
+
+  void OnError(const url::Origin& origin,
+               NetworkFetchCallback callback,
+               FetchError error,
+               const std::string& error_msg);
+
+  // Download requests that are in progress.
+  UrlLoaderList loaders_in_progress_;
+
+  const base::Clock& clock_;
+
+  StoragePartition& storage_partition_;
+
+  // Lazily accessed URLLoaderFactory used for network requests.
+  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
+
+  base::WeakPtrFactory<AggregationServiceNetworkFetcherImpl> weak_factory_{
+      this};
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_AGGREGATION_SERVICE_AGGREGATION_SERVICE_NETWORK_FETCHER_IMPL_H_
diff --git a/content/browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc
new file mode 100644
index 0000000..5d52989
--- /dev/null
+++ b/content/browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc
@@ -0,0 +1,294 @@
+// Copyright 2021 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/aggregation_service/aggregation_service_network_fetcher_impl.h"
+
+#include <memory>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "base/callback_helpers.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/test/bind.h"
+#include "base/time/time.h"
+#include "content/browser/aggregation_service/aggregation_service_test_utils.h"
+#include "content/browser/aggregation_service/public_key.h"
+#include "content/public/test/browser_task_environment.h"
+#include "net/base/load_flags.h"
+#include "net/base/net_errors.h"
+#include "net/http/http_status_code.h"
+#include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/url_loader_completion_status.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/public/mojom/url_response_head.mojom.h"
+#include "services/network/test/test_url_loader_factory.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+#include "url/origin.h"
+
+namespace content {
+
+namespace {
+
+const char kExampleOrigin[] = "https://helper.test/";
+const char kExampleOriginKeysUrl[] =
+    "https://helper.test/.well-known/aggregation-service/keys.json";
+
+const char kExampleValidJson[] = R"(
+        {
+            "version" : "",
+            "keys" : [
+                {
+                    "id" : "abcd",
+                    "key" : "ABCD1234"
+                }
+            ]
+        }
+    )";
+
+const std::vector<PublicKey> kExamplePublicKeys = {
+    PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes)};
+
+}  // namespace
+
+class AggregationServiceNetworkFetcherTest : public testing::Test {
+ public:
+  AggregationServiceNetworkFetcherTest()
+      : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
+        network_fetcher_(std::make_unique<AggregationServiceNetworkFetcherImpl>(
+            task_environment_.GetMockClock(),
+            /*storage_partition=*/nullptr)),
+        shared_url_loader_factory_(
+            base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+                &test_url_loader_factory_)) {
+    network_fetcher_->SetURLLoaderFactoryForTesting(shared_url_loader_factory_);
+  }
+
+ protected:
+  content::BrowserTaskEnvironment task_environment_;
+
+  std::unique_ptr<AggregationServiceNetworkFetcherImpl> network_fetcher_;
+  network::TestURLLoaderFactory test_url_loader_factory_;
+
+ private:
+  scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
+  data_decoder::test::InProcessDataDecoder in_process_data_decoder_;
+};
+
+TEST_F(AggregationServiceNetworkFetcherTest, RequestAttributes) {
+  network_fetcher_->FetchPublicKeys(url::Origin::Create(GURL(kExampleOrigin)),
+                                    std::move(base::DoNothing()));
+
+  EXPECT_EQ(1, test_url_loader_factory_.NumPending());
+
+  const network::ResourceRequest& request =
+      test_url_loader_factory_.GetPendingRequest(0)->request;
+
+  EXPECT_EQ(request.url, kExampleOriginKeysUrl);
+  EXPECT_EQ(request.method, net::HttpRequestHeaders::kGetMethod);
+  EXPECT_EQ(request.credentials_mode, network::mojom::CredentialsMode::kOmit);
+
+  int load_flags = request.load_flags;
+  EXPECT_TRUE(load_flags & net::LOAD_BYPASS_CACHE);
+  EXPECT_TRUE(load_flags & net::LOAD_DISABLE_CACHE);
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest, FetchPublicKeys_Success) {
+  bool callback_run = false;
+  network_fetcher_->FetchPublicKeys(
+      url::Origin::Create(GURL(kExampleOrigin)),
+      base::BindLambdaForTesting([&](absl::optional<PublicKeyset> keyset) {
+        EXPECT_TRUE(keyset.has_value());
+        EXPECT_TRUE(aggregation_service::PublicKeysEqual(kExamplePublicKeys,
+                                                         keyset->keys));
+        callback_run = true;
+      }));
+
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+  EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+      kExampleOriginKeysUrl, kExampleValidJson));
+  EXPECT_TRUE(callback_run);
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest,
+       FetchPublicKeysInvalidKeyFormat_Failed) {
+  bool callback_run = false;
+  network_fetcher_->FetchPublicKeys(
+      url::Origin::Create(GURL(kExampleOrigin)),
+      base::BindLambdaForTesting([&](absl::optional<PublicKeyset> keyset) {
+        EXPECT_FALSE(keyset.has_value());
+        callback_run = true;
+      }));
+
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+  EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+      kExampleOriginKeysUrl, /*content=*/"{}"));
+  EXPECT_TRUE(callback_run);
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest,
+       FetchPublicKeysMalformedJson_Failed) {
+  bool callback_run = false;
+  network_fetcher_->FetchPublicKeys(
+      url::Origin::Create(GURL(kExampleOrigin)),
+      base::BindLambdaForTesting([&](absl::optional<PublicKeyset> keyset) {
+        EXPECT_FALSE(keyset.has_value());
+        callback_run = true;
+      }));
+
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+  EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+      kExampleOriginKeysUrl, /*content=*/"{"));
+  EXPECT_TRUE(callback_run);
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest, FetchPublicKeysLargeBody_Failed) {
+  bool callback_run = false;
+  network_fetcher_->FetchPublicKeys(
+      url::Origin::Create(GURL(kExampleOrigin)),
+      base::BindLambdaForTesting([&](absl::optional<PublicKeyset> keyset) {
+        EXPECT_FALSE(keyset.has_value());
+        callback_run = true;
+      }));
+
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+
+  std::string response_body = kExampleValidJson + std::string(1000000, ' ');
+  EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+      kExampleOriginKeysUrl, response_body));
+  EXPECT_TRUE(callback_run);
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest,
+       FetcherDeletedDuringRequest_NoCrash) {
+  network_fetcher_->FetchPublicKeys(url::Origin::Create(GURL(kExampleOrigin)),
+                                    std::move(base::DoNothing()));
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+  network_fetcher_.reset();
+  EXPECT_FALSE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+      kExampleOriginKeysUrl, kExampleValidJson));
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest, FetchRequestHangs_TimesOut) {
+  bool callback_run = false;
+  network_fetcher_->FetchPublicKeys(
+      url::Origin::Create(GURL(kExampleOrigin)),
+      base::BindLambdaForTesting([&](absl::optional<PublicKeyset> keyset) {
+        EXPECT_FALSE(keyset.has_value());
+        callback_run = true;
+      }));
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+
+  // The request should time out after 30 seconds.
+  task_environment_.FastForwardBy(base::TimeDelta::FromSeconds(30));
+
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 0);
+  EXPECT_FALSE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+      kExampleOriginKeysUrl, kExampleValidJson));
+  EXPECT_TRUE(callback_run);
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest,
+       FetchRequestFailsDueToNetworkChange_Retries) {
+  // Retry fails
+  {
+    bool callback_run = false;
+    network_fetcher_->FetchPublicKeys(
+        url::Origin::Create(GURL(kExampleOrigin)),
+        base::BindLambdaForTesting([&](absl::optional<PublicKeyset> keyset) {
+          EXPECT_FALSE(keyset.has_value());
+          callback_run = true;
+        }));
+    EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+
+    // Simulate the request failing due to network change.
+    test_url_loader_factory_.SimulateResponseForPendingRequest(
+        GURL(kExampleOriginKeysUrl),
+        network::URLLoaderCompletionStatus(net::ERR_NETWORK_CHANGED),
+        network::mojom::URLResponseHead::New(), std::string());
+
+    // The sender should automatically retry.
+    EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+
+    // Simulate a second request failure due to network change.
+    test_url_loader_factory_.SimulateResponseForPendingRequest(
+        GURL(kExampleOriginKeysUrl),
+        network::URLLoaderCompletionStatus(net::ERR_NETWORK_CHANGED),
+        network::mojom::URLResponseHead::New(), std::string());
+
+    // We should not retry again.
+    EXPECT_EQ(test_url_loader_factory_.NumPending(), 0);
+    EXPECT_TRUE(callback_run);
+  }
+
+  // Retry succeeds
+  {
+    bool callback_run = false;
+    network_fetcher_->FetchPublicKeys(
+        url::Origin::Create(GURL(kExampleOrigin)),
+        base::BindLambdaForTesting([&](absl::optional<PublicKeyset> keyset) {
+          EXPECT_TRUE(keyset.has_value());
+          EXPECT_TRUE(aggregation_service::PublicKeysEqual(kExamplePublicKeys,
+                                                           keyset->keys));
+          callback_run = true;
+        }));
+    EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+
+    // Simulate the request failing due to network change.
+    test_url_loader_factory_.SimulateResponseForPendingRequest(
+        GURL(kExampleOriginKeysUrl),
+        network::URLLoaderCompletionStatus(net::ERR_NETWORK_CHANGED),
+        network::mojom::URLResponseHead::New(), std::string());
+
+    // The sender should automatically retry.
+    EXPECT_EQ(test_url_loader_factory_.NumPending(), 1);
+
+    // Simulate a second request with respoonse.
+    EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+        kExampleOriginKeysUrl, kExampleValidJson));
+    EXPECT_TRUE(callback_run);
+  }
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest, HttpError_CallbackRuns) {
+  url::Origin origin = url::Origin::Create(GURL(kExampleOrigin));
+  bool callback_run = false;
+  network_fetcher_->FetchPublicKeys(
+      origin,
+      base::BindLambdaForTesting(
+          [&](absl::optional<PublicKeyset> keyset) { callback_run = true; }));
+
+  // We should run the callback even if there is an http error.
+  EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+      kExampleOriginKeysUrl, /*content=*/"",
+      net::HttpStatusCode::HTTP_BAD_REQUEST));
+
+  EXPECT_TRUE(callback_run);
+}
+
+TEST_F(AggregationServiceNetworkFetcherTest, MultipleRequests_AllCallbacksRun) {
+  url::Origin origin = url::Origin::Create(GURL(kExampleOrigin));
+  int num_callbacks_run = 0;
+  for (int i = 0; i < 10; i++) {
+    network_fetcher_->FetchPublicKeys(
+        origin,
+        base::BindLambdaForTesting(
+            [&](absl::optional<PublicKeyset> keyset) { ++num_callbacks_run; }));
+  }
+
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 10);
+
+  for (int i = 0; i < 10; i++) {
+    EXPECT_TRUE(test_url_loader_factory_.SimulateResponseForPendingRequest(
+        kExampleOriginKeysUrl, kExampleValidJson));
+  }
+
+  EXPECT_EQ(num_callbacks_run, 10);
+  EXPECT_EQ(test_url_loader_factory_.NumPending(), 0);
+}
+
+}  // namespace content
diff --git a/content/browser/aggregation_service/aggregation_service_storage_sql.cc b/content/browser/aggregation_service/aggregation_service_storage_sql.cc
index bafb36c3..1523221 100644
--- a/content/browser/aggregation_service/aggregation_service_storage_sql.cc
+++ b/content/browser/aggregation_service/aggregation_service_storage_sql.cc
@@ -95,12 +95,12 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 }
 
-PublicKeysForOrigin AggregationServiceStorageSql::GetPublicKeys(
+std::vector<PublicKey> AggregationServiceStorageSql::GetPublicKeys(
     const url::Origin& origin) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   DCHECK(network::IsOriginPotentiallyTrustworthy(origin));
 
-  PublicKeysForOrigin result(origin, /*keys=*/{});
+  std::vector<PublicKey> result;
 
   if (!EnsureDatabaseOpen(DbCreationPolicy::kFailIfAbsent))
     return result;
@@ -112,7 +112,7 @@
   get_origin_id_statement.BindString(0, origin.Serialize());
   get_origin_id_statement.BindTime(1, clock_.Now());
   if (!get_origin_id_statement.Step())
-    return PublicKeysForOrigin(origin, {});
+    return result;
 
   int64_t origin_id = get_origin_id_statement.ColumnInt64(0);
 
@@ -125,14 +125,13 @@
 
   bool has_more_data = get_keys_statement.Step();
 
-  while (result.keys.size() < PublicKeysForOrigin::kMaxNumberKeys &&
-         has_more_data) {
+  while (result.size() < PublicKeyset::kMaxNumberKeys && has_more_data) {
     std::string id = get_keys_statement.ColumnString(0);
 
     std::vector<uint8_t> key;
     get_keys_statement.ColumnBlobAsVector(1, &key);
 
-    result.keys.emplace_back(std::move(id), std::move(key));
+    result.emplace_back(std::move(id), std::move(key));
 
     has_more_data = get_keys_statement.Step();
   }
@@ -140,18 +139,16 @@
   // Don't return partial results if one of the statements fails or more keys
   // than expected are returned.
   if (!get_keys_statement.Succeeded() || has_more_data)
-    result.keys.clear();
+    result.clear();
 
   return result;
 }
 
-void AggregationServiceStorageSql::SetPublicKeys(
-    const PublicKeysForOrigin& keys,
-    const base::Time& fetch_time,
-    const base::Time& expiry_time) {
+void AggregationServiceStorageSql::SetPublicKeys(const url::Origin& origin,
+                                                 const PublicKeyset& keyset) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  DCHECK(network::IsOriginPotentiallyTrustworthy(keys.origin));
-  DCHECK_LE(keys.keys.size(), PublicKeysForOrigin::kMaxNumberKeys);
+  DCHECK(network::IsOriginPotentiallyTrustworthy(origin));
+  DCHECK_LE(keyset.keys.size(), PublicKeyset::kMaxNumberKeys);
 
   // TODO(crbug.com/1231703): Add an allowlist for helper server origins and
   // validate the origin.
@@ -167,10 +164,10 @@
 
   // Replace the public keys for the origin. Deleting the existing rows and
   // inserting new ones to reduce the complexity.
-  if (!ClearPublicKeysImpl(keys.origin))
+  if (!ClearPublicKeysImpl(origin))
     return;
 
-  if (!InsertPublicKeysImpl(keys, fetch_time, expiry_time))
+  if (!InsertPublicKeysImpl(origin, keyset))
     return;
 
   transaction.Commit();
@@ -291,11 +288,10 @@
 }
 
 bool AggregationServiceStorageSql::InsertPublicKeysImpl(
-    const PublicKeysForOrigin& keys,
-    const base::Time& fetch_time,
-    const base::Time& expiry_time) {
-  DCHECK(!fetch_time.is_null());
-  DCHECK(!expiry_time.is_null());
+    const url::Origin& origin,
+    const PublicKeyset& keyset) {
+  DCHECK(!keyset.fetch_time.is_null());
+  DCHECK(!keyset.expiry_time.is_null());
   DCHECK(db_.HasActiveTransactions());
 
   static constexpr char kInsertOriginSql[] =
@@ -303,9 +299,9 @@
 
   sql::Statement insert_origin_statement(
       db_.GetCachedStatement(SQL_FROM_HERE, kInsertOriginSql));
-  insert_origin_statement.BindString(0, keys.origin.Serialize());
-  insert_origin_statement.BindTime(1, fetch_time);
-  insert_origin_statement.BindTime(2, expiry_time);
+  insert_origin_statement.BindString(0, origin.Serialize());
+  insert_origin_statement.BindTime(1, keyset.fetch_time);
+  insert_origin_statement.BindTime(2, keyset.expiry_time);
 
   if (!insert_origin_statement.Run())
     return false;
@@ -317,7 +313,7 @@
   sql::Statement insert_key_statement(
       db_.GetCachedStatement(SQL_FROM_HERE, kInsertKeySql));
 
-  for (const PublicKey& key : keys.keys) {
+  for (const PublicKey& key : keyset.keys) {
     DCHECK_LE(key.id.size(), PublicKey::kMaxIdSize);
 
     // TODO(crbug.com/1238458): Check that the key size is as expected.
diff --git a/content/browser/aggregation_service/aggregation_service_storage_sql.h b/content/browser/aggregation_service/aggregation_service_storage_sql.h
index 88349ead..43934a6 100644
--- a/content/browser/aggregation_service/aggregation_service_storage_sql.h
+++ b/content/browser/aggregation_service/aggregation_service_storage_sql.h
@@ -7,6 +7,8 @@
 
 #include "stdint.h"
 
+#include <vector>
+
 #include "base/compiler_specific.h"
 #include "base/files/file_path.h"
 #include "base/sequence_checker.h"
@@ -19,7 +21,6 @@
 
 namespace base {
 class Clock;
-class Time;
 }  // namespace base
 
 namespace sql {
@@ -32,7 +33,8 @@
 
 namespace content {
 
-struct PublicKeysForOrigin;
+struct PublicKey;
+struct PublicKeyset;
 
 // AggregationServiceKeyStorage implementation backed by a SQLite database.
 // Instances may be constructed on any sequence but must be accessed and
@@ -54,10 +56,9 @@
   ~AggregationServiceStorageSql() override;
 
   // AggregationServiceKeyStorage:
-  PublicKeysForOrigin GetPublicKeys(const url::Origin& origin) override;
-  void SetPublicKeys(const PublicKeysForOrigin& keys,
-                     const base::Time& fetch_time,
-                     const base::Time& expiry_time) override;
+  std::vector<PublicKey> GetPublicKeys(const url::Origin& origin) override;
+  void SetPublicKeys(const url::Origin& origin,
+                     const PublicKeyset& keyset) override;
   void ClearPublicKeys(const url::Origin& origin) override;
   void ClearPublicKeysFetchedBetween(base::Time delete_begin,
                                      base::Time delete_end) override;
@@ -100,9 +101,8 @@
   };
 
   // Inserts public keys to database.
-  bool InsertPublicKeysImpl(const PublicKeysForOrigin& keys,
-                            const base::Time& fetch_time,
-                            const base::Time& expiry_time)
+  bool InsertPublicKeysImpl(const url::Origin& origin,
+                            const PublicKeyset& keyset)
       VALID_CONTEXT_REQUIRED(sequence_checker_);
 
   // Deletes all stored public keys for `origin` from database.
diff --git a/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc b/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc
index 4451f75..20821df 100644
--- a/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc
+++ b/content/browser/aggregation_service/aggregation_service_storage_sql_unittest.cc
@@ -5,6 +5,8 @@
 #include "content/browser/aggregation_service/aggregation_service_storage_sql.h"
 
 #include <memory>
+#include <utility>
+#include <vector>
 
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -15,7 +17,6 @@
 #include "content/browser/aggregation_service/aggregation_service_test_utils.h"
 #include "content/browser/aggregation_service/public_key.h"
 #include "sql/database.h"
-#include "sql/test/scoped_error_expecter.h"
 #include "sql/test/test_helpers.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "url/gurl.h"
@@ -25,12 +26,13 @@
 
 namespace {
 
-PublicKeysForOrigin CreateDummyKeys() {
-  return PublicKeysForOrigin(
-      url::Origin::Create(GURL("https://a.com")),
-      {PublicKey(/*id=*/"dummy_id", /*key=*/kABCD1234AsBytes)});
+url::Origin GetExampleOrigin() {
+  return url::Origin::Create(GURL("https://example.com"));
 }
 
+const std::vector<PublicKey> kExampleKeys{
+    PublicKey(/*id=*/"dummy_id", /*key=*/kABCD1234AsBytes)};
+
 }  // namespace
 
 class AggregationServiceStorageSqlTest : public testing::Test {
@@ -83,9 +85,10 @@
   base::HistogramTester histograms;
 
   OpenDatabase();
-  PublicKeysForOrigin keys = CreateDummyKeys();
-  storage_->SetPublicKeys(keys, /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
+  url::Origin origin = GetExampleOrigin();
+  PublicKeyset keyset(kExampleKeys, /*fetch_time=*/clock_.Now(),
+                      /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin, keyset);
   CloseDatabase();
 
   histograms.ExpectUniqueSample(
@@ -98,24 +101,25 @@
   OpenDatabase();
   CloseDatabase();
 
+  url::Origin origin = GetExampleOrigin();
+
   // An unused AggregationServiceStorageSql instance should not create the
   // database.
   EXPECT_FALSE(base::PathExists(db_path()));
 
-  PublicKeysForOrigin keys = CreateDummyKeys();
-
   // Operations which don't need to run on an empty database should not create
   // the database.
   OpenDatabase();
-  EXPECT_TRUE(storage_->GetPublicKeys(keys.origin).keys.empty());
+  EXPECT_TRUE(storage_->GetPublicKeys(origin).empty());
   CloseDatabase();
 
   EXPECT_FALSE(base::PathExists(db_path()));
 
   // Storing a public key should create and initialize the database.
   OpenDatabase();
-  storage_->SetPublicKeys(keys, /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
+  PublicKeyset keyset(kExampleKeys, /*fetch_time=*/clock_.Now(),
+                      /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin, keyset);
   CloseDatabase();
 
   {
@@ -134,14 +138,15 @@
 TEST_F(AggregationServiceStorageSqlTest, DatabaseReopened_DataPersisted) {
   OpenDatabase();
 
-  PublicKeysForOrigin keys = CreateDummyKeys();
-  storage_->SetPublicKeys(keys, /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
-  EXPECT_EQ(storage_->GetPublicKeys(keys.origin).keys.size(), 1u);
+  url::Origin origin = GetExampleOrigin();
+  PublicKeyset keyset(kExampleKeys, /*fetch_time=*/clock_.Now(),
+                      /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin, keyset);
+  EXPECT_EQ(storage_->GetPublicKeys(origin).size(), 1u);
   CloseDatabase();
 
   OpenDatabase();
-  EXPECT_EQ(storage_->GetPublicKeys(keys.origin).keys.size(), 1u);
+  EXPECT_EQ(storage_->GetPublicKeys(origin).size(), 1u);
 }
 
 TEST_F(AggregationServiceStorageSqlTest, SetPublicKeys_ExpectedResult) {
@@ -151,14 +156,13 @@
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"bcde", /*key=*/kEFGH5678AsBytes)};
 
-  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  url::Origin origin = GetExampleOrigin();
+  PublicKeyset keyset(expected_keys, /*fetch_time=*/clock_.Now(),
+                      /*expiry_time=*/base::Time::Max());
 
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin, expected_keys),
-                          /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
-  PublicKeysForOrigin keys_for_origin = storage_->GetPublicKeys(origin);
-  EXPECT_TRUE(aggregation_service::PublicKeysEqual(expected_keys,
-                                                   keys_for_origin.keys));
+  storage_->SetPublicKeys(origin, keyset);
+  std::vector<PublicKey> actual_keys = storage_->GetPublicKeys(origin);
+  EXPECT_TRUE(aggregation_service::PublicKeysEqual(expected_keys, actual_keys));
 
   CloseDatabase();
 }
@@ -166,20 +170,19 @@
 TEST_F(AggregationServiceStorageSqlTest, GetPublicKeysExpired_EmptyResult) {
   OpenDatabase();
 
-  std::vector<PublicKey> expected_keys{
+  std::vector<PublicKey> keys{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"bcde", /*key=*/kEFGH5678AsBytes),
   };
 
   base::Time now = clock_.Now();
-  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  url::Origin origin = GetExampleOrigin();
+  PublicKeyset keyset(std::move(keys), /*fetch_time=*/now,
+                      /*expiry_time=*/now + base::TimeDelta::FromDays(7));
 
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin, expected_keys),
-                          /*fetch_time=*/now,
-                          /*expiry_time=*/now + base::TimeDelta::FromDays(7));
+  storage_->SetPublicKeys(origin, keyset);
   clock_.Advance(base::TimeDelta::FromDays(8));
-  PublicKeysForOrigin keys_for_origin = storage_->GetPublicKeys(origin);
-  EXPECT_TRUE(keys_for_origin.keys.empty());
+  EXPECT_TRUE(storage_->GetPublicKeys(origin).empty());
 
   CloseDatabase();
 }
@@ -187,20 +190,19 @@
 TEST_F(AggregationServiceStorageSqlTest, ClearPublicKeys) {
   OpenDatabase();
 
-  std::vector<PublicKey> expected_keys{
+  std::vector<PublicKey> keys{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"bcde", /*key=*/kEFGH5678AsBytes),
   };
 
-  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  url::Origin origin = GetExampleOrigin();
+  PublicKeyset keyset(std::move(keys), /*fetch_time=*/clock_.Now(),
+                      /*expiry_time=*/base::Time::Max());
 
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin, expected_keys),
-                          /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin, keyset);
   storage_->ClearPublicKeys(origin);
 
-  PublicKeysForOrigin keys_for_origin = storage_->GetPublicKeys(origin);
-  EXPECT_TRUE(keys_for_origin.keys.empty());
+  EXPECT_TRUE(storage_->GetPublicKeys(origin).empty());
 
   CloseDatabase();
 }
@@ -208,28 +210,27 @@
 TEST_F(AggregationServiceStorageSqlTest, ReplacePublicKeys) {
   OpenDatabase();
 
-  base::Time now = clock_.Now();
-  url::Origin origin = url::Origin::Create(GURL("https://a.com"));
+  url::Origin origin = GetExampleOrigin();
 
   std::vector<PublicKey> old_keys{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"bcde", /*key=*/kEFGH5678AsBytes),
   };
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin, old_keys),
-                          /*fetch_time=*/now,
+  PublicKeyset old_keyset(old_keys, /*fetch_time=*/clock_.Now(),
                           /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin, old_keyset);
+  EXPECT_TRUE(aggregation_service::PublicKeysEqual(
+      old_keys, storage_->GetPublicKeys(origin)));
 
   std::vector<PublicKey> expected_keys{
       PublicKey(/*id=*/"efgh", /*key=*/kEFGH5678AsBytes),
       PublicKey(/*id=*/"fghi", /*key=*/kABCD1234AsBytes),
   };
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin, expected_keys),
-                          /*fetch_time=*/now,
-                          /*expiry_time=*/base::Time::Max());
-
-  PublicKeysForOrigin keys_for_origin = storage_->GetPublicKeys(origin);
-  EXPECT_TRUE(aggregation_service::PublicKeysEqual(expected_keys,
-                                                   keys_for_origin.keys));
+  PublicKeyset expected_keyset(expected_keys, /*fetch_time=*/clock_.Now(),
+                               /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin, expected_keyset);
+  EXPECT_TRUE(aggregation_service::PublicKeysEqual(
+      expected_keys, storage_->GetPublicKeys(origin)));
 
   CloseDatabase();
 }
@@ -242,9 +243,9 @@
   std::vector<PublicKey> keys_1{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"bcde", /*key=*/kEFGH5678AsBytes)};
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin_1, keys_1),
-                          /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin_1,
+                          PublicKeyset(keys_1, /*fetch_time=*/clock_.Now(),
+                                       /*expiry_time=*/base::Time::Max()));
 
   clock_.Advance(base::TimeDelta::FromDays(3));
 
@@ -252,22 +253,22 @@
   std::vector<PublicKey> keys_2{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"efgh", /*key=*/kEFGH5678AsBytes)};
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin_2, keys_2),
-                          /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin_2,
+                          PublicKeyset(keys_2, /*fetch_time=*/clock_.Now(),
+                                       /*expiry_time=*/base::Time::Max()));
 
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_1, storage_->GetPublicKeys(origin_1).keys));
+      keys_1, storage_->GetPublicKeys(origin_1)));
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_2, storage_->GetPublicKeys(origin_2).keys));
+      keys_2, storage_->GetPublicKeys(origin_2)));
 
   base::Time now = clock_.Now();
   storage_->ClearPublicKeysFetchedBetween(now - base::TimeDelta::FromDays(5),
                                           now - base::TimeDelta::FromDays(1));
 
-  EXPECT_TRUE(storage_->GetPublicKeys(origin_1).keys.empty());
+  EXPECT_TRUE(storage_->GetPublicKeys(origin_1).empty());
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_2, storage_->GetPublicKeys(origin_2).keys));
+      keys_2, storage_->GetPublicKeys(origin_2)));
 }
 
 TEST_F(AggregationServiceStorageSqlTest, ClearAllPublicKeys_AllDeleted) {
@@ -277,9 +278,9 @@
   std::vector<PublicKey> keys_1{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"bcde", /*key=*/kEFGH5678AsBytes)};
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin_1, keys_1),
-                          /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin_1,
+                          PublicKeyset(keys_1, /*fetch_time=*/clock_.Now(),
+                                       /*expiry_time=*/base::Time::Max()));
 
   clock_.Advance(base::TimeDelta::FromDays(1));
 
@@ -287,19 +288,19 @@
   std::vector<PublicKey> keys_2{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"efgh", /*key=*/kEFGH5678AsBytes)};
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin_2, keys_2),
-                          /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin_2,
+                          PublicKeyset(keys_2, /*fetch_time=*/clock_.Now(),
+                                       /*expiry_time=*/base::Time::Max()));
 
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_1, storage_->GetPublicKeys(origin_1).keys));
+      keys_1, storage_->GetPublicKeys(origin_1)));
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_2, storage_->GetPublicKeys(origin_2).keys));
+      keys_2, storage_->GetPublicKeys(origin_2)));
 
   storage_->ClearPublicKeysFetchedBetween(base::Time(), base::Time::Max());
 
-  EXPECT_TRUE(storage_->GetPublicKeys(origin_1).keys.empty());
-  EXPECT_TRUE(storage_->GetPublicKeys(origin_2).keys.empty());
+  EXPECT_TRUE(storage_->GetPublicKeys(origin_1).empty());
+  EXPECT_TRUE(storage_->GetPublicKeys(origin_2).empty());
 }
 
 TEST_F(AggregationServiceStorageSqlTest,
@@ -312,42 +313,45 @@
   std::vector<PublicKey> keys_1{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"bcde", /*key=*/kEFGH5678AsBytes)};
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin_1, keys_1),
-                          /*fetch_time=*/now,
-                          /*expiry_time=*/now + base::TimeDelta::FromDays(1));
+  storage_->SetPublicKeys(
+      origin_1,
+      PublicKeyset(keys_1, /*fetch_time=*/now,
+                   /*expiry_time=*/now + base::TimeDelta::FromDays(1)));
 
   url::Origin origin_2 = url::Origin::Create(GURL("https://b.com"));
   std::vector<PublicKey> keys_2{
       PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes),
       PublicKey(/*id=*/"efgh", /*key=*/kEFGH5678AsBytes)};
-  storage_->SetPublicKeys(content::PublicKeysForOrigin(origin_2, keys_2),
-                          /*fetch_time=*/now,
-                          /*expiry_time=*/now + base::TimeDelta::FromDays(3));
+  storage_->SetPublicKeys(
+      origin_2,
+      PublicKeyset(keys_2, /*fetch_time=*/now,
+                   /*expiry_time=*/now + base::TimeDelta::FromDays(3)));
 
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_1, storage_->GetPublicKeys(origin_1).keys));
+      keys_1, storage_->GetPublicKeys(origin_1)));
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_2, storage_->GetPublicKeys(origin_2).keys));
+      keys_2, storage_->GetPublicKeys(origin_2)));
 
   storage_->ClearPublicKeysExpiredBy(now + base::TimeDelta::FromDays(1));
 
-  EXPECT_TRUE(storage_->GetPublicKeys(origin_1).keys.empty());
+  EXPECT_TRUE(storage_->GetPublicKeys(origin_1).empty());
   EXPECT_TRUE(aggregation_service::PublicKeysEqual(
-      keys_2, storage_->GetPublicKeys(origin_2).keys));
+      keys_2, storage_->GetPublicKeys(origin_2)));
 }
 
 TEST_F(AggregationServiceStorageSqlInMemoryTest,
        DatabaseInMemoryReopened_DataNotPersisted) {
   OpenDatabase();
 
-  PublicKeysForOrigin keys = CreateDummyKeys();
-  storage_->SetPublicKeys(keys, /*fetch_time=*/clock_.Now(),
-                          /*expiry_time=*/base::Time::Max());
-  EXPECT_EQ(storage_->GetPublicKeys(keys.origin).keys.size(), 1u);
+  url::Origin origin = GetExampleOrigin();
+  PublicKeyset keyset(kExampleKeys, /*fetch_time=*/clock_.Now(),
+                      /*expiry_time=*/base::Time::Max());
+  storage_->SetPublicKeys(origin, keyset);
+  EXPECT_EQ(storage_->GetPublicKeys(origin).size(), 1u);
   CloseDatabase();
 
   OpenDatabase();
-  EXPECT_EQ(storage_->GetPublicKeys(keys.origin).keys.size(), 0u);
+  EXPECT_TRUE(storage_->GetPublicKeys(origin).empty());
 }
 
 }  // namespace content
diff --git a/content/browser/aggregation_service/public_key.cc b/content/browser/aggregation_service/public_key.cc
index f00b296..59f063621 100644
--- a/content/browser/aggregation_service/public_key.cc
+++ b/content/browser/aggregation_service/public_key.cc
@@ -16,21 +16,25 @@
 PublicKey::PublicKey(const PublicKey& other) = default;
 PublicKey& PublicKey::operator=(const PublicKey& other) = default;
 
+PublicKey::PublicKey(PublicKey&& other) = default;
+PublicKey& PublicKey::operator=(PublicKey&& other) = default;
+
 PublicKey::~PublicKey() = default;
 
-PublicKeysForOrigin::PublicKeysForOrigin() = default;
+PublicKeyset::PublicKeyset(std::vector<PublicKey> keys,
+                           base::Time fetch_time,
+                           base::Time expiry_time)
+    : keys(std::move(keys)),
+      fetch_time(std::move(fetch_time)),
+      expiry_time(std::move(expiry_time)) {}
 
-PublicKeysForOrigin::PublicKeysForOrigin(url::Origin origin,
-                                         std::vector<PublicKey> keys)
-    : origin(std::move(origin)), keys(std::move(keys)) {}
+PublicKeyset::PublicKeyset(const PublicKeyset& other) = default;
+PublicKeyset& PublicKeyset::operator=(const PublicKeyset& other) = default;
 
-PublicKeysForOrigin::PublicKeysForOrigin(const PublicKeysForOrigin& other) =
-    default;
+PublicKeyset::PublicKeyset(PublicKeyset&& other) = default;
+PublicKeyset& PublicKeyset::operator=(PublicKeyset&& other) = default;
 
-PublicKeysForOrigin& PublicKeysForOrigin::operator=(
-    const PublicKeysForOrigin& other) = default;
-
-PublicKeysForOrigin::~PublicKeysForOrigin() = default;
+PublicKeyset::~PublicKeyset() = default;
 
 std::ostream& operator<<(std::ostream& out, const PublicKey& public_key) {
   out << "id: " << public_key.id << ", key: 0x"
diff --git a/content/browser/aggregation_service/public_key.h b/content/browser/aggregation_service/public_key.h
index fe9766a..36ca842 100644
--- a/content/browser/aggregation_service/public_key.h
+++ b/content/browser/aggregation_service/public_key.h
@@ -12,17 +12,18 @@
 #include <string>
 #include <vector>
 
+#include "base/time/time.h"
 #include "content/common/content_export.h"
-#include "url/origin.h"
 
 namespace content {
 
 // Contains all the data of a public key.
 struct CONTENT_EXPORT PublicKey {
- public:
   PublicKey(std::string id, std::vector<uint8_t> key);
   PublicKey(const PublicKey& other);
   PublicKey& operator=(const PublicKey& other);
+  PublicKey(PublicKey&& other);
+  PublicKey& operator=(PublicKey&& other);
   ~PublicKey();
 
   // String identifying the key, controlled by the helper server.
@@ -34,15 +35,20 @@
   static constexpr size_t kMaxIdSize = 128;
 };
 
-struct CONTENT_EXPORT PublicKeysForOrigin {
-  PublicKeysForOrigin();
-  PublicKeysForOrigin(url::Origin origin, std::vector<PublicKey> keys);
-  PublicKeysForOrigin(const PublicKeysForOrigin& other);
-  PublicKeysForOrigin& operator=(const PublicKeysForOrigin& other);
-  ~PublicKeysForOrigin();
+struct CONTENT_EXPORT PublicKeyset {
+  PublicKeyset(std::vector<PublicKey> keys,
+               base::Time fetch_time,
+               base::Time expiry_time);
+  PublicKeyset(const PublicKeyset& other);
+  PublicKeyset& operator=(const PublicKeyset& other);
+  PublicKeyset(PublicKeyset&& other);
+  PublicKeyset& operator=(PublicKeyset&& other);
+  ~PublicKeyset();
 
-  url::Origin origin;
   std::vector<PublicKey> keys;
+  base::Time fetch_time;
+  // A null `expiry_time` indicates a response that should not be cached.
+  base::Time expiry_time;
 
   static constexpr size_t kMaxNumberKeys = 10;
 };
diff --git a/content/browser/aggregation_service/public_key_parsing_utils.cc b/content/browser/aggregation_service/public_key_parsing_utils.cc
index 16a881b..7a3503f7 100644
--- a/content/browser/aggregation_service/public_key_parsing_utils.cc
+++ b/content/browser/aggregation_service/public_key_parsing_utils.cc
@@ -65,7 +65,7 @@
   for (auto& key_json : keys_json.value().GetList()) {
     // Return error (i.e. empty vector) if more keys than expected are
     // specified.
-    if (public_keys.size() == PublicKeysForOrigin::kMaxNumberKeys)
+    if (public_keys.size() == PublicKeyset::kMaxNumberKeys)
       return {};
 
     absl::optional<PublicKey> key = GetPublicKey(key_json);
diff --git a/content/browser/compositor/viz_process_transport_factory.cc b/content/browser/compositor/viz_process_transport_factory.cc
index 50ff2c9..53c23a97a 100644
--- a/content/browser/compositor/viz_process_transport_factory.cc
+++ b/content/browser/compositor/viz_process_transport_factory.cc
@@ -167,29 +167,16 @@
       std::move(frame_sink_manager_client_receiver), resize_task_runner_,
       std::move(frame_sink_manager));
 
-  // Hop to the IO thread, then send the other side of interface to viz process.
-  auto connect_on_io_thread =
-      [](mojo::PendingReceiver<viz::mojom::FrameSinkManager> receiver,
-         mojo::PendingRemote<viz::mojom::FrameSinkManagerClient> client,
-         const viz::DebugRendererSettings& debug_renderer_settings) {
-        // There should always be a GpuProcessHost instance, and GPU process,
-        // for running the compositor thread. The exception is during shutdown
-        // the GPU process won't be restarted and GpuProcessHost::Get() can
-        // return null.
-        auto* gpu_process_host = GpuProcessHost::Get();
-        if (gpu_process_host) {
-          gpu_process_host->gpu_host()->ConnectFrameSinkManager(
-              std::move(receiver), std::move(client), debug_renderer_settings);
-        }
-      };
-  auto task = base::BindOnce(
-      connect_on_io_thread, std::move(frame_sink_manager_receiver),
-      std::move(frame_sink_manager_client),
-      GetHostFrameSinkManager()->debug_renderer_settings());
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    std::move(task).Run();
-  } else {
-    GetIOThreadTaskRunner({})->PostTask(FROM_HERE, std::move(task));
+  // There should always be a GpuProcessHost instance, and GPU process,
+  // for running the compositor thread. The exception is during shutdown
+  // the GPU process won't be restarted and GpuProcessHost::Get() can
+  // return null.
+  auto* gpu_process_host = GpuProcessHost::Get();
+  if (gpu_process_host) {
+    gpu_process_host->gpu_host()->ConnectFrameSinkManager(
+        std::move(frame_sink_manager_receiver),
+        std::move(frame_sink_manager_client),
+        GetHostFrameSinkManager()->debug_renderer_settings());
   }
 }
 
diff --git a/content/browser/devtools/protocol/tracing_handler.cc b/content/browser/devtools/protocol/tracing_handler.cc
index 64d1291e..5553d11 100644
--- a/content/browser/devtools/protocol/tracing_handler.cc
+++ b/content/browser/devtools/protocol/tracing_handler.cc
@@ -43,7 +43,6 @@
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/tracing_service.h"
-#include "content/public/common/content_features.h"
 #include "services/resource_coordinator/public/cpp/memory_instrumentation/memory_instrumentation.h"
 #include "services/tracing/public/cpp/perfetto/perfetto_config.h"
 #include "services/tracing/public/cpp/perfetto/perfetto_session.h"
@@ -794,38 +793,14 @@
   did_initiate_recording_ = true;
   trace_config_ = std::move(trace_config);
 
-  // GPU process id can only be retrieved on IO thread. Do some thread hopping.
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? content::GetUIThreadTaskRunner({})
-                         : content::GetIOThreadTaskRunner({});
-  task_runner->PostTaskAndReplyWithResult(
-      FROM_HERE, base::BindOnce([]() {
-        GpuProcessHost* gpu_process_host =
-            GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED,
-                                /* force_create */ false);
-        return gpu_process_host ? gpu_process_host->process_id()
-                                : base::kNullProcessId;
-      }),
-      base::BindOnce(&TracingHandler::StartTracingWithGpuPid,
-                     weak_factory_.GetWeakPtr(), std::move(callback),
-                     *backend));
-}
-
-void TracingHandler::StartTracingWithGpuPid(
-    std::unique_ptr<StartCallback> callback,
-    perfetto::BackendType tracing_backend,
-    base::ProcessId gpu_pid) {
-  // Check if tracing was stopped in mid-air.
-  if (!did_initiate_recording_) {
-    callback->sendFailure(Response::ServerError(
-        "Tracing was stopped before start has been completed."));
-    return;
-  }
-
+  GpuProcessHost* gpu_process_host =
+      GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED,
+                          /* force_create */ false);
+  base::ProcessId gpu_pid =
+      gpu_process_host ? gpu_process_host->process_id() : base::kNullProcessId;
   SetupProcessFilter(gpu_pid, nullptr);
 
-  session_ =
-      std::make_unique<PerfettoTracingSession>(proto_format_, tracing_backend);
+  session_ = std::make_unique<PerfettoTracingSession>(proto_format_, *backend);
   session_->EnableTracing(
       trace_config_,
       base::BindOnce(&TracingHandler::OnRecordingEnabled,
diff --git a/content/browser/devtools/protocol/tracing_handler.h b/content/browser/devtools/protocol/tracing_handler.h
index ea29881..04c802ef 100644
--- a/content/browser/devtools/protocol/tracing_handler.h
+++ b/content/browser/devtools/protocol/tracing_handler.h
@@ -135,9 +135,6 @@
       bool return_as_stream,
       bool proto_format);
   void SetupProcessFilter(base::ProcessId gpu_pid, RenderFrameHost*);
-  void StartTracingWithGpuPid(std::unique_ptr<StartCallback>,
-                              perfetto::BackendType tracing_backend,
-                              base::ProcessId gpu_pid);
   void AppendProcessId(RenderFrameHost*,
                        std::unordered_set<base::ProcessId>* process_set);
   void OnProcessReady(RenderProcessHost*);
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.cc b/content/browser/gpu/browser_gpu_channel_host_factory.cc
index e3f0f0c..926e7ad 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.cc
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.cc
@@ -31,7 +31,6 @@
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/gpu_data_manager.h"
 #include "content/public/common/content_client.h"
-#include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/command_buffer/service/gpu_switches.h"
 #include "gpu/config/gpu_finch_features.h"
@@ -49,26 +48,15 @@
 namespace {
 
 #if defined(OS_ANDROID)
-void TimedOut() {
-  LOG(FATAL) << "Timed out waiting for GPU channel.";
-}
-
 void DumpGpuStackOnProcessThread() {
   GpuProcessHost* host =
       GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED, /*force_create=*/false);
   if (host) {
     host->DumpProcessStack();
   }
-  GetUIThreadTaskRunner({})->PostTask(FROM_HERE, base::BindOnce(&TimedOut));
+  LOG(FATAL) << "Timed out waiting for GPU channel.";
 }
 
-void TimerFired() {
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  task_runner->PostTask(FROM_HERE,
-                        base::BindOnce(&DumpGpuStackOnProcessThread));
-}
 #endif  // OS_ANDROID
 
 }  // namespace
@@ -101,16 +89,15 @@
   EstablishRequest(int gpu_client_id, uint64_t gpu_client_tracing_id);
   ~EstablishRequest() {}
   void RestartTimeout();
-  // Note |sync| is only true if EstablishGpuChannelSync is being called AND
-  // ProcessHostOnUI is enabled. In that case we make the sync mojo call since
-  // we're on the UI thread and therefore can't wait for an async mojo reply on
-  // the same thread.
+  // Note |sync| is only true if EstablishGpuChannelSync is being called. In
+  // that case we make the sync mojo call since we're on the UI thread and
+  // therefore can't wait for an async mojo reply on the same thread.
   void Establish(bool sync);
   void OnEstablished(mojo::ScopedMessagePipeHandle channel_handle,
                      const gpu::GPUInfo& gpu_info,
                      const gpu::GpuFeatureInfo& gpu_feature_info,
                      viz::GpuHostImpl::EstablishChannelStatus status);
-  void FinishOnProcessThread();
+  void Finish();
   void FinishAndRunCallbacksOnMain();
   void FinishOnMain();
   void RunCallbacksOnMain();
@@ -131,17 +118,7 @@
     bool sync) {
   scoped_refptr<EstablishRequest> establish_request =
       new EstablishRequest(gpu_client_id, gpu_client_tracing_id);
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    establish_request->Establish(sync);
-  } else {
-    // PostTask outside the constructor to ensure at least one reference exists.
-    GetIOThreadTaskRunner({})->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            &BrowserGpuChannelHostFactory::EstablishRequest::Establish,
-            establish_request, false));
-  }
-
+  establish_request->Establish(sync);
   return establish_request;
 }
 
@@ -172,7 +149,7 @@
   GpuProcessHost* host = GpuProcessHost::Get();
   if (!host) {
     LOG(ERROR) << "Failed to launch GPU process.";
-    FinishOnProcessThread();
+    Finish();
     return;
   }
 
@@ -203,11 +180,8 @@
         base::BindOnce(
             &BrowserGpuChannelHostFactory::EstablishRequest::RestartTimeout,
             this));
-    auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                           ? GetUIThreadTaskRunner({})
-                           : GetIOThreadTaskRunner({});
     // TODO(jam): can we ever enter this when it was a sync call?
-    task_runner->PostTask(
+    GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
         base::BindOnce(
             &BrowserGpuChannelHostFactory::EstablishRequest::Establish, this,
@@ -220,20 +194,12 @@
         gpu_client_id_, gpu_info, gpu_feature_info, std::move(channel_handle),
         GetIOThreadTaskRunner({}));
   }
-  FinishOnProcessThread();
+  Finish();
 }
 
-void BrowserGpuChannelHostFactory::EstablishRequest::FinishOnProcessThread() {
+void BrowserGpuChannelHostFactory::EstablishRequest::Finish() {
   event_.Signal();
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    FinishAndRunCallbacksOnMain();
-  } else {
-    main_task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&BrowserGpuChannelHostFactory::EstablishRequest::
-                           FinishAndRunCallbacksOnMain,
-                       this));
-  }
+  FinishAndRunCallbacksOnMain();
 }
 
 void BrowserGpuChannelHostFactory::EstablishRequest::
@@ -308,12 +274,7 @@
     gpu_channel_ = nullptr;
   }
 
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI) &&
-      gpu_memory_buffer_manager_) {
-    delete gpu_memory_buffer_manager_.release();
-  } else {
-    gpu_memory_buffer_manager_ = nullptr;
-  }
+  gpu_memory_buffer_manager_.reset();
 }
 
 BrowserGpuChannelHostFactory::BrowserGpuChannelHostFactory()
@@ -327,11 +288,8 @@
     DCHECK(GetContentClient());
     base::FilePath cache_dir =
         GetContentClient()->browser()->GetShaderDiskCacheDirectory();
-    auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                           ? GetUIThreadTaskRunner({})
-                           : GetIOThreadTaskRunner({});
     if (!cache_dir.empty()) {
-      task_runner->PostTask(
+      GetUIThreadTaskRunner({})->PostTask(
           FROM_HERE,
           base::BindOnce(
               &BrowserGpuChannelHostFactory::InitializeShaderDiskCacheOnIO,
@@ -345,7 +303,7 @@
       base::FilePath gr_cache_dir =
           GetContentClient()->browser()->GetGrShaderDiskCacheDirectory();
       if (!gr_cache_dir.empty()) {
-        task_runner->PostTask(
+        GetUIThreadTaskRunner({})->PostTask(
             FROM_HERE,
             base::BindOnce(
                 &BrowserGpuChannelHostFactory::InitializeGrShaderDiskCacheOnIO,
@@ -363,13 +321,6 @@
     gpu_channel_->DestroyChannel();
     gpu_channel_ = nullptr;
   }
-
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI) &&
-      gpu_memory_buffer_manager_) {
-    // Delete this on the main thread (since otherwise the unique_ptr has a
-    // trait to delete it on the IO thread).
-    delete gpu_memory_buffer_manager_.release();
-  }
 }
 
 void BrowserGpuChannelHostFactory::EstablishGpuChannel(
@@ -388,11 +339,6 @@
   return nullptr;
 #else
   EstablishGpuChannel(gpu::GpuChannelEstablishedCallback(), true);
-
-  if (!base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    if (pending_request_.get())
-      pending_request_->Wait();
-  }
   return gpu_channel_;
 #endif
 }
@@ -408,8 +354,7 @@
   }
 
   std::vector<gpu::GpuChannelEstablishedCallback> callbacks;
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI) && sync &&
-      !gpu_channel_ && pending_request_) {
+  if (sync && !gpu_channel_ && pending_request_) {
     // There's a previous request. Cancel it since we must call the synchronous
     // version of the mojo method and the previous call was asynchronous.
     callbacks = pending_request_->TakeCallbacks();
@@ -515,7 +460,7 @@
 
   timeout_.Start(FROM_HERE,
                  base::TimeDelta::FromSeconds(kGpuChannelTimeoutInSeconds),
-                 base::BindOnce(&TimerFired));
+                 base::BindOnce(&DumpGpuStackOnProcessThread));
 #endif  // OS_ANDROID
 }
 
diff --git a/content/browser/gpu/browser_gpu_channel_host_factory.h b/content/browser/gpu/browser_gpu_channel_host_factory.h
index f57c77b..d618d98b 100644
--- a/content/browser/gpu/browser_gpu_channel_host_factory.h
+++ b/content/browser/gpu/browser_gpu_channel_host_factory.h
@@ -18,7 +18,6 @@
 #include "base/timer/timer.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
-#include "content/public/browser/browser_thread.h"
 #include "gpu/ipc/client/gpu_channel_host.h"
 #include "ipc/message_filter.h"
 
@@ -78,8 +77,7 @@
   const int gpu_client_id_;
   const uint64_t gpu_client_tracing_id_;
   scoped_refptr<gpu::GpuChannelHost> gpu_channel_;
-  std::unique_ptr<gpu::GpuMemoryBufferManager, BrowserThread::DeleteOnIOThread>
-      gpu_memory_buffer_manager_;
+  std::unique_ptr<gpu::GpuMemoryBufferManager> gpu_memory_buffer_manager_;
   scoped_refptr<EstablishRequest> pending_request_;
   bool is_visible_ = true;
 
diff --git a/content/browser/gpu/ca_transaction_gpu_coordinator.cc b/content/browser/gpu/ca_transaction_gpu_coordinator.cc
index 1efcc0e7..4ad4313 100644
--- a/content/browser/gpu/ca_transaction_gpu_coordinator.cc
+++ b/content/browser/gpu/ca_transaction_gpu_coordinator.cc
@@ -9,7 +9,6 @@
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
 #include "services/viz/privileged/mojom/gl/gpu_service.mojom.h"
 #include "ui/accelerated_widget_mac/ca_transaction_observer.h"
 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
@@ -23,9 +22,7 @@
       new CATransactionGPUCoordinator(host));
   // Avoid modifying result's refcount in the constructor by performing this
   // PostTask afterward.
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
       FROM_HERE,
       base::BindOnce(
@@ -43,9 +40,7 @@
 }
 
 void CATransactionGPUCoordinator::HostWillBeDestroyed() {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
       FROM_HERE,
       base::BindOnce(
@@ -68,14 +63,8 @@
 
 void CATransactionGPUCoordinator::OnActivateForTransaction() {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    OnActivateForTransactionOnProcessThread();
-  } else {
-    GetIOThreadTaskRunner({})->PostTask(
-        FROM_HERE, base::BindOnce(&CATransactionGPUCoordinator::
-                                      OnActivateForTransactionOnProcessThread,
-                                  this));
-  }
+  if (host_)
+    host_->gpu_service()->BeginCATransaction();
 }
 
 void CATransactionGPUCoordinator::OnEnterPostCommit() {
@@ -86,15 +75,9 @@
   // (and removed from the list of post-commit observers) soon after.
   pending_commit_count_++;
 
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    OnEnterPostCommitOnProcessThread();
-  } else {
-    GetIOThreadTaskRunner({})->PostTask(
-        FROM_HERE,
-        base::BindOnce(
-            &CATransactionGPUCoordinator::OnEnterPostCommitOnProcessThread,
-            this));
-  }
+  if (host_)
+    host_->gpu_service()->CommitCATransaction(base::BindOnce(
+        &CATransactionGPUCoordinator::OnCommitCompletedOnProcessThread, this));
 }
 
 bool CATransactionGPUCoordinator::ShouldWaitInPostCommit() {
@@ -102,27 +85,8 @@
   return pending_commit_count_ > 0;
 }
 
-void CATransactionGPUCoordinator::OnActivateForTransactionOnProcessThread() {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
-  if (host_)
-    host_->gpu_service()->BeginCATransaction();
-}
-
-void CATransactionGPUCoordinator::OnEnterPostCommitOnProcessThread() {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
-  if (host_)
-    host_->gpu_service()->CommitCATransaction(base::BindOnce(
-        &CATransactionGPUCoordinator::OnCommitCompletedOnProcessThread, this));
-}
-
 void CATransactionGPUCoordinator::OnCommitCompletedOnProcessThread() {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
   ui::WindowResizeHelperMac::Get()->task_runner()->PostTask(
       FROM_HERE,
       base::BindOnce(&CATransactionGPUCoordinator::OnCommitCompletedOnUI,
diff --git a/content/browser/gpu/ca_transaction_gpu_coordinator.h b/content/browser/gpu/ca_transaction_gpu_coordinator.h
index 246426a3..74b961a 100644
--- a/content/browser/gpu/ca_transaction_gpu_coordinator.h
+++ b/content/browser/gpu/ca_transaction_gpu_coordinator.h
@@ -34,8 +34,6 @@
   void AddPostCommitObserverOnUIThread();
   void RemovePostCommitObserverOnUIThread();
 
-  void OnActivateForTransactionOnProcessThread();
-  void OnEnterPostCommitOnProcessThread();
   void OnCommitCompletedOnProcessThread();
   void OnCommitCompletedOnUI();
 
diff --git a/content/browser/gpu/chromeos/video_capture_dependencies.cc b/content/browser/gpu/chromeos/video_capture_dependencies.cc
index e135fb24..7bb8910 100644
--- a/content/browser/gpu/chromeos/video_capture_dependencies.cc
+++ b/content/browser/gpu/chromeos/video_capture_dependencies.cc
@@ -9,7 +9,6 @@
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
 
 namespace content {
 
@@ -17,11 +16,8 @@
 void VideoCaptureDependencies::CreateJpegDecodeAccelerator(
     mojo::PendingReceiver<chromeos_camera::mojom::MjpegDecodeAccelerator>
         accelerator) {
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  if (!task_runner->BelongsToCurrentThread()) {
-    task_runner->PostTask(
+  if (!GetUIThreadTaskRunner({})->BelongsToCurrentThread()) {
+    GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
         base::BindOnce(&VideoCaptureDependencies::CreateJpegDecodeAccelerator,
                        std::move(accelerator)));
@@ -42,11 +38,8 @@
 void VideoCaptureDependencies::CreateJpegEncodeAccelerator(
     mojo::PendingReceiver<chromeos_camera::mojom::JpegEncodeAccelerator>
         accelerator) {
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  if (!task_runner->BelongsToCurrentThread()) {
-    task_runner->PostTask(
+  if (!GetUIThreadTaskRunner({})->BelongsToCurrentThread()) {
+    GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
         base::BindOnce(&VideoCaptureDependencies::CreateJpegEncodeAccelerator,
                        std::move(accelerator)));
diff --git a/content/browser/gpu/gpu_client.cc b/content/browser/gpu/gpu_client.cc
index e92f0a8..514c15d3 100644
--- a/content/browser/gpu/gpu_client.cc
+++ b/content/browser/gpu/gpu_client.cc
@@ -8,7 +8,6 @@
 #include "content/common/child_process_host_impl.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
 
 namespace content {
 
@@ -18,9 +17,7 @@
   const int client_id = ChildProcessHostImpl::GenerateChildProcessUniqueId();
   const uint64_t client_tracing_id =
       ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(client_id);
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
+  auto task_runner = GetUIThreadTaskRunner({});
   std::unique_ptr<viz::GpuClient, base::OnTaskRunnerDeleter> gpu_client(
       new viz::GpuClient(
           std::make_unique<BrowserGpuClientDelegate>(), client_id,
diff --git a/content/browser/gpu/gpu_data_manager_impl_private.cc b/content/browser/gpu/gpu_data_manager_impl_private.cc
index 8ec1775..f456cbd5 100644
--- a/content/browser/gpu/gpu_data_manager_impl_private.cc
+++ b/content/browser/gpu/gpu_data_manager_impl_private.cc
@@ -508,36 +508,17 @@
   }
 
   static void RequestHDRStatus() {
-    // The request must be sent to the GPU process from the IO thread.
-    auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                           ? GetUIThreadTaskRunner({})
-                           : GetIOThreadTaskRunner({});
-    task_runner->PostTask(FROM_HERE,
-                          base::BindOnce(&HDRProxy::RequestOnProcessThread));
-  }
-
-  static void GotResultOnProcessThread(bool hdr_enabled) {
-    if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-      GotResult(hdr_enabled);
-    } else {
-      GetUIThreadTaskRunner({})->PostTask(
-          FROM_HERE, base::BindOnce(&HDRProxy::GotResult, hdr_enabled));
-    }
-  }
-
- private:
-  static void RequestOnProcessThread() {
     auto* gpu_process_host =
         GpuProcessHost::Get(GPU_PROCESS_KIND_SANDBOXED, false);
     if (gpu_process_host) {
       auto* gpu_service = gpu_process_host->gpu_host()->gpu_service();
-      gpu_service->RequestHDRStatus(
-          base::BindOnce(&HDRProxy::GotResultOnProcessThread));
+      gpu_service->RequestHDRStatus(base::BindOnce(&HDRProxy::GotResult));
     } else {
       bool hdr_enabled = false;
-      GotResultOnProcessThread(hdr_enabled);
+      GotResult(hdr_enabled);
     }
   }
+
   static void GotResult(bool hdr_enabled) {
     display::win::ScreenWin::SetHDREnabled(hdr_enabled);
   }
@@ -753,10 +734,7 @@
         }));
   });
 
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  task_runner->PostTask(FROM_HERE, std::move(task));
+  GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(task));
 #endif
 }
 
@@ -823,10 +801,7 @@
       },
       delta);
 
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  task_runner->PostDelayedTask(FROM_HERE, std::move(task), delta);
+  GetUIThreadTaskRunner({})->PostDelayedTask(FROM_HERE, std::move(task), delta);
 #endif
 }
 
@@ -875,10 +850,7 @@
       },
       delta);
 
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  task_runner->PostDelayedTask(FROM_HERE, std::move(task), delta);
+  GetUIThreadTaskRunner({})->PostDelayedTask(FROM_HERE, std::move(task), delta);
 #endif
 }
 
@@ -900,10 +872,7 @@
         }));
   });
 
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  task_runner->PostTask(FROM_HERE, std::move(task));
+  GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(task));
 }
 
 void GpuDataManagerImplPrivate::RequestMojoMediaVideoCapabilities() {
@@ -933,11 +902,7 @@
         std::move(remote_decoder)));
   });
 
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  DCHECK(task_runner);
-  task_runner->PostTask(FROM_HERE, std::move(task));
+  GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(task));
 }
 
 bool GpuDataManagerImplPrivate::IsEssentialGpuInfoAvailable() const {
@@ -1129,11 +1094,9 @@
 }
 
 void GpuDataManagerImplPrivate::UpdateHDRStatus(bool hdr_enabled) {
-  // This is running on the process thread;
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
-  HDRProxy::GotResultOnProcessThread(hdr_enabled);
+  // This is running on the main thread;
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  HDRProxy::GotResult(hdr_enabled);
 }
 
 void GpuDataManagerImplPrivate::UpdateDxDiagNodeRequestStatus(
diff --git a/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc b/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc
index 8e693a86..103db8f 100644
--- a/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc
+++ b/content/browser/gpu/gpu_memory_buffer_manager_singleton.cc
@@ -12,7 +12,6 @@
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
 #include "gpu/ipc/common/gpu_memory_buffer_support.h"
 #include "ui/base/ui_base_features.h"
 
@@ -51,9 +50,6 @@
 #endif
 
 scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() {
-  if (!base::FeatureList::IsEnabled(features::kProcessHostOnUI))
-    return GetIOThreadTaskRunner({});
-
 #if defined(OS_MAC)
   return ui::WindowResizeHelperMac::Get()->task_runner();
 #else
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc
index cc842d8..3a8decde 100644
--- a/content/browser/gpu/gpu_process_host.cc
+++ b/content/browser/gpu/gpu_process_host.cc
@@ -576,9 +576,7 @@
 
 // static
 GpuProcessHost* GpuProcessHost::Get(GpuProcessKind kind, bool force_create) {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Do not launch the unsandboxed GPU info collection process if GPU is
   // disabled
@@ -621,12 +619,8 @@
 
 // static
 void GpuProcessHost::GetHasGpuProcess(base::OnceCallback<void(bool)> callback) {
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-
-  if (!task_runner->BelongsToCurrentThread()) {
-    task_runner->PostTask(
+  if (!GetUIThreadTaskRunner({})->BelongsToCurrentThread()) {
+    GetUIThreadTaskRunner({})->PostTask(
         FROM_HERE,
         base::BindOnce(&GpuProcessHost::GetHasGpuProcess, std::move(callback)));
     return;
@@ -650,12 +644,9 @@
 #if !defined(OS_WIN)
   DCHECK_NE(kind, GPU_PROCESS_KIND_INFO_COLLECTION);
 #endif
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
-  task_runner->PostTask(FROM_HERE,
-                        base::BindOnce(&RunCallbackOnIO, kind, force_create,
-                                       std::move(callback)));
+  GetUIThreadTaskRunner({})->PostTask(
+      FROM_HERE, base::BindOnce(&RunCallbackOnIO, kind, force_create,
+                                std::move(callback)));
 }
 
 void GpuProcessHost::BindInterface(
@@ -685,9 +676,7 @@
 
 // static
 GpuProcessHost* GpuProcessHost::FromID(int host_id) {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   for (int i = 0; i < GPU_PROCESS_KIND_COUNT; ++i) {
     GpuProcessHost* host = g_gpu_process_hosts[i];
@@ -895,9 +884,7 @@
   mode_ = GpuDataManagerImpl::GetInstance()->GetGpuMode();
 
   if (in_process_) {
-    DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                            ? BrowserThread::UI
-                            : BrowserThread::IO);
+    DCHECK_CURRENTLY_ON(BrowserThread::UI);
     DCHECK(GetGpuMainThreadFactory());
     gpu::GpuPreferences gpu_preferences = GetGpuPreferencesFromCommandLine();
     GpuDataManagerImpl::GetInstance()->UpdateGpuPreferences(
@@ -1104,14 +1091,7 @@
 void GpuProcessHost::BindDiscardableMemoryReceiver(
     mojo::PendingReceiver<
         discardable_memory::mojom::DiscardableSharedMemoryManager> receiver) {
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
     BindDiscardableMemoryReceiverOnUI(std::move(receiver));
-    return;
-  }
-
-  GetUIThreadTaskRunner({})->PostTask(
-      FROM_HERE,
-      base::BindOnce(&BindDiscardableMemoryReceiverOnUI, std::move(receiver)));
 }
 
 GpuProcessKind GpuProcessHost::kind() {
diff --git a/content/browser/gpu/in_process_gpu_thread_browsertests.cc b/content/browser/gpu/in_process_gpu_thread_browsertests.cc
index eddc512..8e4af7d 100644
--- a/content/browser/gpu/in_process_gpu_thread_browsertests.cc
+++ b/content/browser/gpu/in_process_gpu_thread_browsertests.cc
@@ -28,20 +28,6 @@
   }
 };
 
-void CreateGpuProcessHost() {
-  GpuProcessHost::Get();
-}
-
-void WaitUntilGpuProcessHostIsCreated() {
-  base::RunLoop run_loop;
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? content::GetUIThreadTaskRunner({})
-                         : content::GetIOThreadTaskRunner({});
-  task_runner->PostTaskAndReply(
-      FROM_HERE, base::BindOnce(&CreateGpuProcessHost), run_loop.QuitClosure());
-  run_loop.Run();
-}
-
 // Reproduces the race that could give crbug.com/799002's "hang until OOM" at
 // shutdown.
 IN_PROC_BROWSER_TEST_F(InProcessGpuTest, NoHangAtQuickLaunchAndShutDown) {
@@ -50,7 +36,7 @@
 
 // Tests crbug.com/799002 but with another timing.
 IN_PROC_BROWSER_TEST_F(InProcessGpuTest, NoCrashAtShutdown) {
-  WaitUntilGpuProcessHostIsCreated();
+  GpuProcessHost::Get();
   // ... then exit the browser.
 }
 
diff --git a/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc b/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc
index d6bfe3a..2d1d4909 100644
--- a/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc
+++ b/content/browser/gpu/peak_gpu_memory_tracker_impl_browsertest.cc
@@ -15,7 +15,6 @@
 #include "content/browser/gpu/gpu_process_host.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/content_browser_test.h"
 #include "content/public/test/test_utils.h"
@@ -144,15 +143,6 @@
   base::RepeatingClosure quit_closure_;
 };
 
-// Runs |task| on the Browser's IO thread, and blocks the Main thread until that
-// task has ran.
-void PostTaskToIOThreadAndWait(base::OnceClosure task) {
-  base::RunLoop run_loop;
-  content::GetIOThreadTaskRunner({})->PostTaskAndReply(
-      FROM_HERE, std::move(task), run_loop.QuitClosure());
-  run_loop.Run();
-}
-
 }  // namespace
 
 class PeakGpuMemoryTrackerImplTest : public ContentBrowserTest {
@@ -163,26 +153,7 @@
   // Waits until all messages to the mojo::Remote<viz::mojom::GpuService> have
   // been processed.
   void FlushRemoteForTesting() {
-    if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-      gpu_host_impl_test_api_->FlushRemoteForTesting();
-    } else {
-      PostTaskToIOThreadAndWait(
-          base::BindOnce(&viz::GpuHostImplTestApi::FlushRemoteForTesting,
-                         base::Unretained(gpu_host_impl_test_api_.get())));
-    }
-  }
-
-  // Initializes the TestGpuService, and installs it as the active service.
-  void InitOnProcessThread(base::RepeatingClosure quit_closure) {
-    gpu_host_impl_test_api_ = std::make_unique<viz::GpuHostImplTestApi>(
-        GpuProcessHost::Get()->gpu_host());
-    test_gpu_service_ = std::make_unique<TestGpuService>(quit_closure);
-    mojo::Remote<viz::mojom::GpuService> gpu_service_remote;
-    gpu_service_receiver_ =
-        std::make_unique<mojo::Receiver<viz::mojom::GpuService>>(
-            test_gpu_service_.get(),
-            gpu_service_remote.BindNewPipeAndPassReceiver());
-    gpu_host_impl_test_api_->SetGpuService(std::move(gpu_service_remote));
+    gpu_host_impl_test_api_->FlushRemoteForTesting();
   }
 
   void SetTestingCallback(PeakGpuMemoryTracker* tracker,
@@ -200,23 +171,21 @@
   void PreRunTestOnMainThread() override {
     run_loop_for_start_ = std::make_unique<base::RunLoop>();
     ContentBrowserTest::PreRunTestOnMainThread();
-    if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-      InitOnProcessThread(run_loop_for_start_->QuitClosure());
-    } else {
-      PostTaskToIOThreadAndWait(base::BindOnce(
-          &PeakGpuMemoryTrackerImplTest::InitOnProcessThread,
-          base::Unretained(this), run_loop_for_start_->QuitClosure()));
-    }
+
+    // Initializes the TestGpuService, and installs it as the active service.
+    gpu_host_impl_test_api_ = std::make_unique<viz::GpuHostImplTestApi>(
+        GpuProcessHost::Get()->gpu_host());
+    test_gpu_service_ =
+        std::make_unique<TestGpuService>(run_loop_for_start_->QuitClosure());
+    mojo::Remote<viz::mojom::GpuService> gpu_service_remote;
+    gpu_service_receiver_ =
+        std::make_unique<mojo::Receiver<viz::mojom::GpuService>>(
+            test_gpu_service_.get(),
+            gpu_service_remote.BindNewPipeAndPassReceiver());
+    gpu_host_impl_test_api_->SetGpuService(std::move(gpu_service_remote));
   }
   void PostRunTestOnMainThread() override {
-    if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-      gpu_service_receiver_.reset();
-    } else {
-      PostTaskToIOThreadAndWait(base::BindOnce(
-          [](std::unique_ptr<mojo::Receiver<viz::mojom::GpuService>>
-                 gpu_service_receiver) {},
-          std::move(gpu_service_receiver_)));
-    }
+    gpu_service_receiver_.reset();
     ContentBrowserTest::PostRunTestOnMainThread();
   }
 
diff --git a/content/browser/media/dcomp_surface_registry_broker.cc b/content/browser/media/dcomp_surface_registry_broker.cc
index 04d9150..720092d 100644
--- a/content/browser/media/dcomp_surface_registry_broker.cc
+++ b/content/browser/media/dcomp_surface_registry_broker.cc
@@ -4,22 +4,22 @@
 
 #include "content/browser/media/dcomp_surface_registry_broker.h"
 
-#include "base/feature_list.h"
 #include "base/logging.h"
 #include "content/browser/gpu/gpu_process_host.h"
-#include "content/public/browser/browser_task_traits.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
 #include "media/base/bind_to_current_loop.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
 
 namespace content {
 
-namespace {
+DCOMPSurfaceRegistryBroker::DCOMPSurfaceRegistryBroker() = default;
 
-void RegisterDCOMPSurfaceHandleInternal(
+DCOMPSurfaceRegistryBroker::~DCOMPSurfaceRegistryBroker() = default;
+
+void DCOMPSurfaceRegistryBroker::RegisterDCOMPSurfaceHandle(
     mojo::PlatformHandle surface_handle,
-    DCOMPSurfaceRegistryBroker::RegisterDCOMPSurfaceHandleCallback callback) {
+    RegisterDCOMPSurfaceHandleCallback callback) {
+  DVLOG(1) << __func__;
+
   auto* gpu_process_host =
       GpuProcessHost::Get(GpuProcessKind::GPU_PROCESS_KIND_SANDBOXED, false);
   if (!gpu_process_host) {
@@ -34,7 +34,10 @@
                                      std::move(callback), absl::nullopt));
 }
 
-void UnregisterDCOMPSurfaceHandleInternal(const base::UnguessableToken& token) {
+void DCOMPSurfaceRegistryBroker::UnregisterDCOMPSurfaceHandle(
+    const base::UnguessableToken& token) {
+  DVLOG(1) << __func__;
+
   auto* gpu_process_host =
       GpuProcessHost::Get(GpuProcessKind::GPU_PROCESS_KIND_SANDBOXED, false);
   if (!gpu_process_host) {
@@ -46,40 +49,4 @@
   gpu_service->UnregisterDCOMPSurfaceHandle(token);
 }
 
-}  // namespace
-
-DCOMPSurfaceRegistryBroker::DCOMPSurfaceRegistryBroker() = default;
-
-DCOMPSurfaceRegistryBroker::~DCOMPSurfaceRegistryBroker() = default;
-
-void DCOMPSurfaceRegistryBroker::RegisterDCOMPSurfaceHandle(
-    mojo::PlatformHandle surface_handle,
-    RegisterDCOMPSurfaceHandleCallback callback) {
-  DVLOG(1) << __func__;
-
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    RegisterDCOMPSurfaceHandleInternal(std::move(surface_handle),
-                                       std::move(callback));
-  } else {
-    GetIOThreadTaskRunner({})->PostTask(
-        FROM_HERE,
-        base::BindOnce(&RegisterDCOMPSurfaceHandleInternal,
-                       std::move(surface_handle),
-                       media::BindToCurrentLoop(std::move(callback))));
-  }
-}
-
-void DCOMPSurfaceRegistryBroker::UnregisterDCOMPSurfaceHandle(
-    const base::UnguessableToken& token) {
-  DVLOG(1) << __func__;
-
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    UnregisterDCOMPSurfaceHandleInternal(token);
-  } else {
-    GetIOThreadTaskRunner({})->PostTask(
-        FROM_HERE,
-        base::BindOnce(&UnregisterDCOMPSurfaceHandleInternal, token));
-  }
-}
-
 }  // namespace content
diff --git a/content/browser/media/media_service.cc b/content/browser/media/media_service.cc
index 408946d..36405b9 100644
--- a/content/browser/media/media_service.cc
+++ b/content/browser/media/media_service.cc
@@ -9,7 +9,6 @@
 #include "base/time/time.h"
 #include "content/public/browser/browser_task_traits.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/common/content_features.h"
 #include "media/mojo/buildflags.h"
 #include "media/mojo/mojom/media_service.mojom.h"
 #include "mojo/public/cpp/bindings/remote.h"
@@ -23,26 +22,6 @@
 
 namespace content {
 
-namespace {
-
-#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
-void BindReceiverInGpuProcess(
-    mojo::PendingReceiver<media::mojom::MediaService> receiver) {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
-  auto* process_host = GpuProcessHost::Get();
-  if (!process_host) {
-    DLOG(ERROR) << "GPU process host not available";
-    return;
-  }
-
-  process_host->RunService(std::move(receiver));
-}
-#endif
-
-}  // namespace
-
 media::mojom::MediaService& GetMediaService() {
   // NOTE: We use sequence-local storage to limit the lifetime of this Remote to
   // that of the UI-thread sequence. This ensures that the Remote is destroyed
@@ -57,12 +36,11 @@
     remote.reset_on_disconnect();
 
 #if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
-    if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-      BindReceiverInGpuProcess(std::move(receiver));
+    auto* process_host = GpuProcessHost::Get();
+    if (process_host) {
+      process_host->RunService(std::move(receiver));
     } else {
-      GetIOThreadTaskRunner({})->PostTask(
-          FROM_HERE,
-          base::BindOnce(&BindReceiverInGpuProcess, std::move(receiver)));
+      DLOG(ERROR) << "GPU process host not available";
     }
 #elif BUILDFLAG(ENABLE_MOJO_MEDIA_IN_BROWSER_PROCESS)
     static_assert(media::mojom::MediaService::kServiceSandbox ==
diff --git a/content/browser/metrics/histogram_controller.cc b/content/browser/metrics/histogram_controller.cc
index c73b240..0d3ab39 100644
--- a/content/browser/metrics/histogram_controller.cc
+++ b/content/browser/metrics/histogram_controller.cc
@@ -15,7 +15,6 @@
 #include "content/public/browser/child_process_data.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/common/child_process_host.h"
-#include "content/public/common/content_features.h"
 #include "content/public/common/process_type.h"
 #include "mojo/public/cpp/bindings/callback_helpers.h"
 
@@ -30,14 +29,6 @@
 
 HistogramController::~HistogramController() {}
 
-void HistogramController::OnPendingProcesses(int sequence_number,
-                                             int pending_processes,
-                                             bool end) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  if (subscriber_)
-    subscriber_->OnPendingProcesses(sequence_number, pending_processes, end);
-}
-
 void HistogramController::OnHistogramDataCollected(
     int sequence_number,
     const std::vector<std::string>& pickled_histograms) {
@@ -134,13 +125,25 @@
   GetChildHistogramFetcherMap<T>().erase(host);
 }
 
-void HistogramController::GetHistogramDataFromChildProcesses(
-    int sequence_number) {
-  DCHECK_CURRENTLY_ON(base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                          ? BrowserThread::UI
-                          : BrowserThread::IO);
+void HistogramController::GetHistogramData(int sequence_number) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   int pending_processes = 0;
+  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
+       !it.IsAtEnd() && it.GetCurrentValue()->IsReady(); it.Advance()) {
+    if (auto* child_histogram_fetcher =
+            GetChildHistogramFetcherInterface(it.GetCurrentValue())) {
+      child_histogram_fetcher->GetChildNonPersistentHistogramData(
+          mojo::WrapCallbackWithDefaultInvokeIfNotRun(
+              base::BindOnce(&HistogramController::OnHistogramDataCollected,
+                             base::Unretained(this), sequence_number),
+              std::vector<std::string>()));
+      ++pending_processes;
+    }
+  }
+
+  // TODO(rtenneti): Enable getting histogram data for other processes like
+  // PPAPI and NACL.
   for (BrowserChildProcessHostIterator iter; !iter.Done(); ++iter) {
     const ChildProcessData& data = iter.GetData();
 
@@ -166,37 +169,9 @@
       ++pending_processes;
     }
   }
-  GetUIThreadTaskRunner({})->PostTask(
-      FROM_HERE, base::BindOnce(&HistogramController::OnPendingProcesses,
-                                base::Unretained(this), sequence_number,
-                                pending_processes, true));
-}
 
-void HistogramController::GetHistogramData(int sequence_number) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  int pending_processes = 0;
-  for (RenderProcessHost::iterator it(RenderProcessHost::AllHostsIterator());
-       !it.IsAtEnd() && it.GetCurrentValue()->IsReady(); it.Advance()) {
-    if (auto* child_histogram_fetcher =
-            GetChildHistogramFetcherInterface(it.GetCurrentValue())) {
-      child_histogram_fetcher->GetChildNonPersistentHistogramData(
-          mojo::WrapCallbackWithDefaultInvokeIfNotRun(
-              base::BindOnce(&HistogramController::OnHistogramDataCollected,
-                             base::Unretained(this), sequence_number),
-              std::vector<std::string>()));
-      ++pending_processes;
-    }
-  }
-  OnPendingProcesses(sequence_number, pending_processes, false);
-
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? content::GetUIThreadTaskRunner({})
-                         : content::GetIOThreadTaskRunner({});
-  task_runner->PostTask(
-      FROM_HERE,
-      base::BindOnce(&HistogramController::GetHistogramDataFromChildProcesses,
-                     base::Unretained(this), sequence_number));
+  if (subscriber_)
+    subscriber_->OnPendingProcesses(sequence_number, pending_processes, true);
 }
 
 }  // namespace content
diff --git a/content/browser/metrics/histogram_controller.h b/content/browser/metrics/histogram_controller.h
index 7150345..9f70d6d 100644
--- a/content/browser/metrics/histogram_controller.h
+++ b/content/browser/metrics/histogram_controller.h
@@ -52,13 +52,6 @@
   // Contact all processes and get their histogram data.
   void GetHistogramData(int sequence_number);
 
-  // Notify the |subscriber_| that it should expect at least |pending_processes|
-  // additional calls to OnHistogramDataCollected().  OnPendingProcess() may be
-  // called repeatedly; the last call will have |end| set to true, indicating
-  // that there is no longer a possibility for the count of pending processes to
-  // increase.  This is called on the UI thread.
-  void OnPendingProcesses(int sequence_number, int pending_processes, bool end);
-
   // Send the |histogram| back to the |subscriber_|.
   // This can be called from any thread.
   void OnHistogramDataCollected(
@@ -76,11 +69,6 @@
  private:
   friend struct base::LeakySingletonTraits<HistogramController>;
 
-  // Contact PLUGIN and GPU child processes and get their histogram data.
-  // TODO(rtenneti): Enable getting histogram data for other processes like
-  // PPAPI and NACL.
-  void GetHistogramDataFromChildProcesses(int sequence_number);
-
   HistogramSubscriber* subscriber_;
 
   template <class T>
diff --git a/content/browser/renderer_host/clipboard_host_impl_unittest.cc b/content/browser/renderer_host/clipboard_host_impl_unittest.cc
index 4ac57053..ebf0a4b0 100644
--- a/content/browser/renderer_host/clipboard_host_impl_unittest.cc
+++ b/content/browser/renderer_host/clipboard_host_impl_unittest.cc
@@ -85,10 +85,10 @@
                     content::RenderFrameHost* rfh,
                     base::OnceCallback<void(bool)> callback));
 
-  MOCK_METHOD3(IsDragDropAllowed,
-               bool(const ui::DataTransferEndpoint* const data_src,
-                    const ui::DataTransferEndpoint* const data_dst,
-                    const bool is_drop));
+  MOCK_METHOD3(DropIfAllowed,
+               void(const ui::DataTransferEndpoint* data_src,
+                    const ui::DataTransferEndpoint* data_dst,
+                    base::OnceClosure drop_cb));
 };
 
 }  // namespace
diff --git a/content/browser/renderer_host/compositor_dependencies_android.cc b/content/browser/renderer_host/compositor_dependencies_android.cc
index a8a369f..6a9cc86 100644
--- a/content/browser/renderer_host/compositor_dependencies_android.cc
+++ b/content/browser/renderer_host/compositor_dependencies_android.cc
@@ -108,8 +108,8 @@
 
   // Set up a pending request which will be run once we've successfully
   // connected to the GPU process.
-  pending_connect_viz_on_process_thread_ = base::BindOnce(
-      &CompositorDependenciesAndroid::ConnectVizFrameSinkManagerOnProcessThread,
+  pending_connect_viz_on_main_thread_ = base::BindOnce(
+      &CompositorDependenciesAndroid::ConnectVizFrameSinkManagerOnMainThread,
       std::move(frame_sink_manager_receiver),
       std::move(frame_sink_manager_client),
       host_frame_sink_manager_.debug_renderer_settings());
@@ -126,14 +126,9 @@
 }
 
 void CompositorDependenciesAndroid::TryEstablishVizConnectionIfNeeded() {
-  if (!pending_connect_viz_on_process_thread_)
+  if (!pending_connect_viz_on_main_thread_)
     return;
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    std::move(pending_connect_viz_on_process_thread_).Run();
-  } else {
-    GetIOThreadTaskRunner({})->PostTask(
-        FROM_HERE, std::move(pending_connect_viz_on_process_thread_));
-  }
+  std::move(pending_connect_viz_on_main_thread_).Run();
 }
 
 // Called on the GpuProcessHost thread, after a GPU connection has already been
@@ -141,7 +136,7 @@
 // established and lost. In this case the ConnectionLost callback will be
 // re-run when the request is deleted (goes out of scope).
 // static
-void CompositorDependenciesAndroid::ConnectVizFrameSinkManagerOnProcessThread(
+void CompositorDependenciesAndroid::ConnectVizFrameSinkManagerOnMainThread(
     mojo::PendingReceiver<viz::mojom::FrameSinkManager> receiver,
     mojo::PendingRemote<viz::mojom::FrameSinkManagerClient> client,
     const viz::DebugRendererSettings& debug_renderer_settings) {
diff --git a/content/browser/renderer_host/compositor_dependencies_android.h b/content/browser/renderer_host/compositor_dependencies_android.h
index b4fdb38..c1b4fc24 100644
--- a/content/browser/renderer_host/compositor_dependencies_android.h
+++ b/content/browser/renderer_host/compositor_dependencies_android.h
@@ -43,7 +43,7 @@
  private:
   friend class base::NoDestructor<CompositorDependenciesAndroid>;
 
-  static void ConnectVizFrameSinkManagerOnProcessThread(
+  static void ConnectVizFrameSinkManagerOnMainThread(
       mojo::PendingReceiver<viz::mojom::FrameSinkManager> receiver,
       mojo::PendingRemote<viz::mojom::FrameSinkManagerClient> client,
       const viz::DebugRendererSettings& debug_renderer_settings);
@@ -63,8 +63,8 @@
   // when we hide, canceled when we're shown.
   base::CancelableOnceClosure low_end_background_cleanup_task_;
 
-  // A callback which connects to the viz service on the GpuProcessHost thread.
-  base::OnceClosure pending_connect_viz_on_process_thread_;
+  // A callback which connects to the viz service on the main thread.
+  base::OnceClosure pending_connect_viz_on_main_thread_;
 
   // The set of visible CompositorImpls.
   base::flat_set<CompositorImpl*> visible_compositors_;
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index 9cb6c43..fd68285 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -1740,12 +1740,9 @@
   const int id = GetID();
   const uint64_t tracing_id =
       ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(id);
-  auto task_runner = base::FeatureList::IsEnabled(features::kProcessHostOnUI)
-                         ? GetUIThreadTaskRunner({})
-                         : GetIOThreadTaskRunner({});
   gpu_client_.reset(
       new viz::GpuClient(std::make_unique<BrowserGpuClientDelegate>(), id,
-                         tracing_id, task_runner));
+                         tracing_id, GetUIThreadTaskRunner({})));
 }
 
 // static
@@ -1836,13 +1833,6 @@
   if (cleanup_network_service_plugin_exceptions_upon_destruction_)
     RemoveNetworkServicePluginExceptions(GetID());
 
-
-  // Manually delete here in order to avoid DeleteOnIOThread trait when
-  // kProcessHostOnUI is enabled.
-  DCHECK(gpu_client_);
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI))
-    delete gpu_client_.release();
-
   // "Cleanup in progress"
   TRACE_EVENT_END("shutdown", perfetto::Track::FromPointer(this),
                   ChromeTrackEvent::kRenderProcessHost, *this);
@@ -2531,17 +2521,9 @@
       base::BindRepeating(&FileSystemManagerImpl::BindReceiver,
                           base::Unretained(file_system_manager_impl_.get())));
 
-  // |gpu_client_| outlives the registry, because its destruction is posted to
-  // IO thread from the destructor of |this|.
-  if (base::FeatureList::IsEnabled(features::kProcessHostOnUI)) {
-    AddUIThreadInterface(
-        registry.get(),
-        base::BindRepeating(&viz::GpuClient::Add,
-                            base::Unretained(gpu_client_.get())));
-  } else {
-    registry->AddInterface(base::BindRepeating(
-        &viz::GpuClient::Add, base::Unretained(gpu_client_.get())));
-  }
+  AddUIThreadInterface(
+      registry.get(), base::BindRepeating(&viz::GpuClient::Add,
+                                          base::Unretained(gpu_client_.get())));
 
   registry->AddInterface(
       base::BindRepeating(&GpuDataManagerImpl::BindReceiver));
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 9eff3892..30916df 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -1113,7 +1113,7 @@
 
   std::unique_ptr<FileSystemManagerImpl, BrowserThread::DeleteOnIOThread>
       file_system_manager_impl_;
-  std::unique_ptr<viz::GpuClient, BrowserThread::DeleteOnIOThread> gpu_client_;
+  std::unique_ptr<viz::GpuClient> gpu_client_;
   std::unique_ptr<PushMessagingManager> push_messaging_manager_;
 
   std::unique_ptr<EmbeddedFrameSinkProviderImpl> embedded_frame_sink_provider_;
diff --git a/content/browser/service_worker/embedded_worker_test_helper.cc b/content/browser/service_worker/embedded_worker_test_helper.cc
index ac389b95..9796ce1 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.cc
+++ b/content/browser/service_worker/embedded_worker_test_helper.cc
@@ -36,8 +36,13 @@
           std::make_unique<MockRenderProcessHost>(browser_context_.get())),
       new_render_process_host_(
           std::make_unique<MockRenderProcessHost>(browser_context_.get())),
+      quota_manager_(base::MakeRefCounted<storage::MockQuotaManager>(
+          /*is_cognito=*/false,
+          user_data_directory,
+          base::ThreadTaskRunnerHandle::Get(),
+          special_storage_policy)),
       quota_manager_proxy_(base::MakeRefCounted<storage::MockQuotaManagerProxy>(
-          nullptr,
+          quota_manager_.get(),
           base::SequencedTaskRunnerHandle::Get())),
       wrapper_(base::MakeRefCounted<ServiceWorkerContextWrapper>(
           browser_context_.get())),
diff --git a/content/browser/service_worker/embedded_worker_test_helper.h b/content/browser/service_worker/embedded_worker_test_helper.h
index c42086c7..52b2e55b 100644
--- a/content/browser/service_worker/embedded_worker_test_helper.h
+++ b/content/browser/service_worker/embedded_worker_test_helper.h
@@ -192,6 +192,7 @@
   std::unique_ptr<TestBrowserContext> browser_context_;
   std::unique_ptr<MockRenderProcessHost> render_process_host_;
   std::unique_ptr<MockRenderProcessHost> new_render_process_host_;
+  scoped_refptr<storage::MockQuotaManager> quota_manager_;
   scoped_refptr<storage::MockQuotaManagerProxy> quota_manager_proxy_;
 
   scoped_refptr<ServiceWorkerContextWrapper> wrapper_;
diff --git a/content/browser/tracing/background_tracing_config_unittest.cc b/content/browser/tracing/background_tracing_config_unittest.cc
index 2e5c538..eefa270d 100644
--- a/content/browser/tracing/background_tracing_config_unittest.cc
+++ b/content/browser/tracing/background_tracing_config_unittest.cc
@@ -115,6 +115,37 @@
   EXPECT_FALSE(ReadFromJSONString(
       "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
       "\"configs\": [{\"rule\": \"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\"}]}"));
+
+  // Missing or invalid keys for a histogram trigger.
+  EXPECT_FALSE(ReadFromJSONString(
+      "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
+      "\"configs\": [{\"rule\": "
+      "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+      "\"histogram_name\":\"foo\"}]}"));
+  EXPECT_FALSE(ReadFromJSONString(
+      "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
+      "\"configs\": [{\"rule\": "
+      "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+      "\"histogram_lower_value\": 1, \"histogram_upper_value\": 2}]}"));
+  EXPECT_FALSE(ReadFromJSONString(
+      "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
+      "\"configs\": [{\"rule\": "
+      "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+      "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1,"
+      "\"histogram_upper_value\": 1}]}"));
+  // `units` must be an int from the HistogramRule::Units enum.
+  EXPECT_FALSE(ReadFromJSONString(
+      "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
+      "\"configs\": [{\"rule\": "
+      "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+      "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1,"
+      "\"histogram_upper_value\": 2, \"histogram_units\": \"bar\"}]}"));
+  EXPECT_FALSE(ReadFromJSONString(
+      "{\"mode\":\"preemptive\", \"category\": \"benchmark\","
+      "\"configs\": [{\"rule\": "
+      "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+      "\"histogram_name\":\"foo\", \"histogram_lower_value\": 1,"
+      "\"histogram_upper_value\": 2, \"histogram_units\": 100}]}"));
 }
 
 TEST_F(BackgroundTracingConfigTest, ReactiveConfigFromInvalidString) {
@@ -255,6 +286,39 @@
   config = ReadFromJSONString(
       "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
       "\"BENCHMARK_STARTUP\",\"configs\": [{\"rule\": "
+      "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+      "\"histogram_name\":\"foo\", \"histogram_value\": 1, "
+      "\"histogram_units\": 0}]}");
+  EXPECT_TRUE(config);
+  EXPECT_EQ(config->tracing_mode(), BackgroundTracingConfig::PREEMPTIVE);
+  EXPECT_EQ(config->category_preset(),
+            BackgroundTracingConfigImpl::BENCHMARK_STARTUP);
+  EXPECT_EQ(config->rules().size(), 1u);
+  EXPECT_EQ(RuleToString(config->rules()[0]),
+            "{\"histogram_lower_value\":1,\"histogram_name\":\"foo\","
+            "\"histogram_repeat\":true,\"histogram_upper_value\":2147483647,"
+            "\"rule\":\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
+
+  config = ReadFromJSONString(
+      "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
+      "\"BENCHMARK_STARTUP\",\"configs\": [{\"rule\": "
+      "\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\", "
+      "\"histogram_name\":\"foo\", \"histogram_value\": 1, "
+      "\"histogram_units\": 1}]}");
+  EXPECT_TRUE(config);
+  EXPECT_EQ(config->tracing_mode(), BackgroundTracingConfig::PREEMPTIVE);
+  EXPECT_EQ(config->category_preset(),
+            BackgroundTracingConfigImpl::BENCHMARK_STARTUP);
+  EXPECT_EQ(config->rules().size(), 1u);
+  EXPECT_EQ(RuleToString(config->rules()[0]),
+            "{\"histogram_lower_value\":1,\"histogram_name\":\"foo\","
+            "\"histogram_repeat\":true,\"histogram_units\":1,"
+            "\"histogram_upper_value\":2147483647,"
+            "\"rule\":\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}");
+
+  config = ReadFromJSONString(
+      "{\"mode\":\"PREEMPTIVE_TRACING_MODE\", \"category\": "
+      "\"BENCHMARK_STARTUP\",\"configs\": [{\"rule\": "
       "\"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\", \"trigger_name\":\"foo1\"}, "
       "{\"rule\": \"MONITOR_AND_DUMP_WHEN_TRIGGER_NAMED\", "
       "\"trigger_name\":\"foo2\"}]}");
@@ -538,6 +602,28 @@
         "SPECIFIC_HISTOGRAM_AND_VALUE\",\"trigger_delay\":10}],\"mode\":"
         "\"PREEMPTIVE_TRACING_MODE\"}");
   }
+
+  {
+    config = std::make_unique<BackgroundTracingConfigImpl>(
+        BackgroundTracingConfig::PREEMPTIVE);
+
+    base::Value second_dict(base::Value::Type::DICTIONARY);
+    second_dict.SetStringKey(
+        "rule", "MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE");
+    second_dict.SetStringKey("histogram_name", "foo");
+    second_dict.SetIntKey("histogram_lower_value", 1);
+    second_dict.SetIntKey("histogram_upper_value", 2);
+    second_dict.SetIntKey("histogram_units", 1);
+    config->AddPreemptiveRule(second_dict);
+
+    EXPECT_EQ(
+        ConfigToString(config.get()),
+        "{\"category\":\"BENCHMARK_STARTUP\",\"configs\":[{\"histogram_lower_"
+        "value\":1,\"histogram_name\":\"foo\",\"histogram_repeat\":true,"
+        "\"histogram_units\":1,\"histogram_upper_value\":2,"
+        "\"rule\":\"MONITOR_AND_DUMP_WHEN_SPECIFIC_HISTOGRAM_AND_VALUE\"}],"
+        "\"mode\":\"PREEMPTIVE_TRACING_MODE\"}");
+  }
 }
 
 TEST_F(BackgroundTracingConfigTest, InvalidPreemptiveConfigToString) {
diff --git a/content/browser/tracing/background_tracing_rule.cc b/content/browser/tracing/background_tracing_rule.cc
index eb05037f..7420e2c 100644
--- a/content/browser/tracing/background_tracing_rule.cc
+++ b/content/browser/tracing/background_tracing_rule.cc
@@ -5,6 +5,7 @@
 
 #include <limits>
 #include <string>
+#include <type_traits>
 
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
@@ -16,6 +17,7 @@
 #include "base/strings/strcat.h"
 #include "base/timer/timer.h"
 #include "base/trace_event/trace_event.h"
+#include "base/trace_event/trace_id_helper.h"
 #include "base/values.h"
 #include "content/browser/tracing/background_tracing_manager_impl.h"
 #include "content/public/browser/browser_task_traits.h"
@@ -43,6 +45,7 @@
 const char kConfigRuleHistogramValue1Key[] = "histogram_lower_value";
 const char kConfigRuleHistogramValue2Key[] = "histogram_upper_value";
 const char kConfigRuleHistogramRepeatKey[] = "histogram_repeat";
+const char kConfigRuleHistogramUnitsKey[] = "histogram_units";
 
 const char kConfigRuleRandomIntervalTimeoutMin[] = "timeout_min";
 const char kConfigRuleRandomIntervalTimeoutMax[] = "timeout_max";
@@ -208,13 +211,38 @@
 class HistogramRule : public BackgroundTracingRule,
                       public BackgroundTracingManagerImpl::AgentObserver {
  private:
+  // Units that can be displayed specially in OnHistogramChangedCallback.
+  enum class Units : int {
+    kUnspecified = 0,
+    kMilliseconds,
+    kMicroseconds,
+  };
+
+  static Units IntToUnits(int units_value) {
+    static_assert(std::is_same<std::underlying_type_t<Units>,
+                               decltype(units_value)>::value,
+                  "not safe to cast units_value to Units");
+    Units units = static_cast<Units>(units_value);
+    switch (units) {
+      case Units::kUnspecified:
+      case Units::kMilliseconds:
+      case Units::kMicroseconds:
+        // Recognized enum value.
+        return units;
+    }
+    // Unrecognized enum value.
+    return Units::kUnspecified;
+  }
+
   HistogramRule(const std::string& histogram_name,
                 int histogram_lower_value,
                 int histogram_upper_value,
+                Units units,
                 bool repeat)
       : histogram_name_(histogram_name),
         histogram_lower_value_(histogram_lower_value),
         histogram_upper_value_(histogram_upper_value),
+        units_(units),
         repeat_(repeat),
         installed_(false) {}
 
@@ -245,9 +273,13 @@
     if (*histogram_lower_value >= histogram_upper_value)
       return nullptr;
 
+    Units units = Units::kUnspecified;
+    if (auto units_value = dict.FindIntKey(kConfigRuleHistogramUnitsKey)) {
+      units = IntToUnits(*units_value);
+    }
     std::unique_ptr<BackgroundTracingRule> rule(
         new HistogramRule(*histogram_name, *histogram_lower_value,
-                          histogram_upper_value, repeat));
+                          histogram_upper_value, units, repeat));
 
     const base::Value* args_dict = dict.FindDictKey(kConfigRuleArgsKey);
     if (args_dict)
@@ -268,7 +300,7 @@
         histogram_name_,
         base::BindRepeating(&HistogramRule::OnHistogramChangedCallback,
                             base::Unretained(this), histogram_lower_value_,
-                            histogram_upper_value_, repeat_));
+                            histogram_upper_value_, units_, repeat_));
     BackgroundTracingManagerImpl::GetInstance()->AddAgentObserver(this);
     installed_ = true;
   }
@@ -280,6 +312,8 @@
     dict.SetStringKey(kConfigRuleHistogramNameKey, histogram_name_.c_str());
     dict.SetIntKey(kConfigRuleHistogramValue1Key, histogram_lower_value_);
     dict.SetIntKey(kConfigRuleHistogramValue2Key, histogram_upper_value_);
+    if (units_ != Units::kUnspecified)
+      dict.SetIntKey(kConfigRuleHistogramUnitsKey, static_cast<int>(units_));
     dict.SetBoolKey(kConfigRuleHistogramRepeatKey, repeat_);
     return dict;
   }
@@ -328,6 +362,7 @@
 
   void OnHistogramChangedCallback(base::Histogram::Sample reference_lower_value,
                                   base::Histogram::Sample reference_upper_value,
+                                  Units units,
                                   bool repeat,
                                   const char* histogram_name,
                                   uint64_t name_hash,
@@ -344,15 +379,35 @@
                          "BackgroundTracingRule::OnHistogramTrigger",
                          TRACE_EVENT_SCOPE_THREAD, "histogram_name",
                          histogram_name, "value", actual_value);
-
-    TRACE_EVENT(
-        "toplevel",
-        "HistogramSampleTrigger", [&](perfetto::EventContext ctx) {
-          perfetto::protos::pbzero::ChromeHistogramSample* new_sample =
-              ctx.event()->set_chrome_histogram_sample();
-          new_sample->set_name_hash(base::HashMetricName(histogram_name));
-          new_sample->set_sample(actual_value);
-        });
+    const auto trace_details = [&](perfetto::EventContext ctx) {
+      perfetto::protos::pbzero::ChromeHistogramSample* new_sample =
+          ctx.event()->set_chrome_histogram_sample();
+      new_sample->set_name_hash(base::HashMetricName(histogram_name));
+      new_sample->set_sample(actual_value);
+    };
+    const auto track =
+        perfetto::Track::FromPointer(this, perfetto::ProcessTrack::Current());
+    const auto now = base::TimeTicks::Now();
+    if (units == Units::kUnspecified) {
+      TRACE_EVENT_INSTANT("toplevel", "HistogramSampleTrigger", track, now,
+                          trace_details);
+    } else {
+      base::TimeDelta delta;
+      switch (units) {
+        case Units::kUnspecified:
+          NOTREACHED();  // Handled above.
+          break;
+        case Units::kMilliseconds:
+          delta = base::TimeDelta::FromMilliseconds(actual_value);
+          break;
+        case Units::kMicroseconds:
+          delta = base::TimeDelta::FromMicroseconds(actual_value);
+          break;
+      }
+      TRACE_EVENT_BEGIN("toplevel", "HistogramSampleTrigger", track,
+                        now - delta, trace_details);
+      TRACE_EVENT_END("toplevel", track, now);
+    }
 
     OnHistogramTrigger(histogram_name);
   }
@@ -370,6 +425,7 @@
   std::string histogram_name_;
   int histogram_lower_value_;
   int histogram_upper_value_;
+  Units units_;
   bool repeat_;
   bool installed_;
   std::unique_ptr<base::StatisticsRecorder::ScopedHistogramSampleObserver>
diff --git a/content/browser/webauth/authenticator_common.cc b/content/browser/webauth/authenticator_common.cc
index 2de940b4..fa6712a 100644
--- a/content/browser/webauth/authenticator_common.cc
+++ b/content/browser/webauth/authenticator_common.cc
@@ -1246,9 +1246,12 @@
     requested_extensions_.insert(RequestExtension::kLargeBlobWrite);
   }
 
-  timer_->Start(
-      FROM_HERE, AdjustTimeout(options->timeout, GetRenderFrameHost()),
-      base::BindOnce(&AuthenticatorCommon::OnTimeout, base::Unretained(this)));
+  if (!options->is_conditional) {
+    timer_->Start(FROM_HERE,
+                  AdjustTimeout(options->timeout, GetRenderFrameHost()),
+                  base::BindOnce(&AuthenticatorCommon::OnTimeout,
+                                 base::Unretained(this)));
+  }
 
   ctap_get_assertion_request_ =
       CreateCtapGetAssertionRequest(client_data_json_, options, app_id_,
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn
index 84568bc..8561b088 100644
--- a/content/public/android/BUILD.gn
+++ b/content/public/android/BUILD.gn
@@ -99,7 +99,6 @@
     "java/src/org/chromium/content/app/PrivilegedProcessService3.java",
     "java/src/org/chromium/content/app/PrivilegedProcessService4.java",
     "java/src/org/chromium/content/app/SandboxedProcessService.java",
-    "java/src/org/chromium/content/app/ZygotePreload.java",
     "java/src/org/chromium/content/browser/BrowserStartupControllerImpl.java",
     "java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java",
     "java/src/org/chromium/content/browser/ContentChildProcessConstants.java",
@@ -110,6 +109,7 @@
     "java/src/org/chromium/content/common/ContentSwitchUtils.java",
     "java/src/org/chromium/content/common/SurfaceWrapper.java",
     "java/src/org/chromium/content_public/app/ChildProcessServiceFactory.java",
+    "java/src/org/chromium/content_public/app/ZygotePreload.java",
     "java/src/org/chromium/content_public/browser/BrowserStartupController.java",
     "java/src/org/chromium/content_public/browser/BrowserTaskExecutor.java",
     "java/src/org/chromium/content_public/browser/ChildProcessCreationParams.java",
diff --git a/content/public/android/java/src/org/chromium/content/app/ZygotePreload.java b/content/public/android/java/src/org/chromium/content_public/app/ZygotePreload.java
similarity index 74%
rename from content/public/android/java/src/org/chromium/content/app/ZygotePreload.java
rename to content/public/android/java/src/org/chromium/content_public/app/ZygotePreload.java
index 83067291..92e30da 100644
--- a/content/public/android/java/src/org/chromium/content/app/ZygotePreload.java
+++ b/content/public/android/java/src/org/chromium/content_public/app/ZygotePreload.java
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.content.app;
+package org.chromium.content_public.app;
 
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
@@ -32,13 +32,19 @@
     @SuppressLint("Override")
     @Override
     public void doPreload(ApplicationInfo appInfo) {
-        try {
-            // Using concatenation rather than %s to allow values to be inlined by R8.
-            Log.i(TAG,
-                    "Loaded Zygote. version=" + VersionConstants.PRODUCT_VERSION
-                            + " minSdkVersion=" + BuildConfig.MIN_SDK_VERSION
-                            + " isBundle=" + BuildConfig.BUNDLES_SUPPORTED);
+        // Non-trichrome zygotes always use the system linker.
+        doPreloadCommon(appInfo, /* useModernLinker= */ false);
+    }
 
+    protected final void doPreloadCommon(ApplicationInfo appInfo, boolean useModernLinker) {
+        // Using concatenation rather than %s to allow values to be inlined by R8.
+        Log.i(TAG,
+                "Loaded Zygote. version=" + VersionConstants.PRODUCT_VERSION
+                        + " minSdkVersion=" + BuildConfig.MIN_SDK_VERSION
+                        + " isBundle=" + BuildConfig.BUNDLES_SUPPORTED);
+        try {
+            LibraryLoader.getInstance().setLinkerImplementation(
+                    /* useChromiumLinker= */ useModernLinker, useModernLinker);
             // The current thread time is the best approximation we have of the zygote start time
             // since Process.getStartUptimeMillis() is not reliable in the zygote process. This will
             // be the total CPU time the current thread has been running, and is reset on fork so
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
index 56ed0d8..504d1b186 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
@@ -42,6 +42,8 @@
             "Test expectations were null, perhaps the file is missing?";
     private static final String RESULTS_NULL =
             "Test results were null, did you remember to add the tracker to WCAI?";
+    private static final String MISSING_FILE_ERROR =
+            "Input file could not be read, perhaps the file is missing?";
 
     // Member variables required for testing framework
     private static final String BASE_DIRECTORY = "/chromium_tests_root";
@@ -62,6 +64,9 @@
      */
     /* @Before */
     protected void setupTestFromFile(String filepath) {
+        // Verify file exists before beginning the test.
+        verifyInputFile(filepath);
+
         mActivityTestRule.launchContentShellWithUrl(UrlUtils.getIsolatedTestFileUrl(filepath));
         mActivityTestRule.waitForActiveShellToBeDoneLoading();
         mActivityTestRule.setupTestFramework();
@@ -177,6 +182,17 @@
         }
     }
 
+    /**
+     * Check that a given file exists on disk.
+     * @param fileName      String - file to check
+     */
+    private void verifyInputFile(String fileName) {
+        String directory = Environment.getExternalStorageDirectory().getPath() + BASE_DIRECTORY;
+
+        File expectedFile = new File(directory, "/" + fileName);
+        Assert.assertTrue(MISSING_FILE_ERROR, expectedFile.exists());
+    }
+
     // Helper pass-through methods to make tests easier to read.
     private <T> int waitForNodeMatching(
             AccessibilityContentShellTestUtils.AccessibilityNodeInfoMatcher<T> matcher, T element) {
@@ -885,12 +901,6 @@
 
     @Test
     @SmallTest
-    public void test_menulistPopup() {
-        performTest("menulist-popup.html", EMPTY_EXPECTATIONS_FILE);
-    }
-
-    @Test
-    @SmallTest
     public void test_menuOpenedClosed() {
         performTest("menu-opened-closed.html", EMPTY_EXPECTATIONS_FILE);
     }
diff --git a/content/public/test/test_download_http_response.cc b/content/public/test/test_download_http_response.cc
index b9b67e14..311482e2 100644
--- a/content/public/test/test_download_http_response.cc
+++ b/content/public/test/test_download_http_response.cc
@@ -304,7 +304,7 @@
   if (GetResponseForRangeRequest(&response, &delay_response)) {
     if (delay_response) {
       delayed_response_callback_ =
-          base::BindOnce(bytes_sender_, response, GenerateResultClosure()),
+          base::BindOnce(bytes_sender_, response, GenerateResultClosure());
       bytes_sender_.Run(GetDefaultResponseHeaders(), base::DoNothing());
     } else {
       bytes_sender_.Run(response, GenerateResultClosure());
diff --git a/content/shell/android/shell_apk/AndroidManifest.xml.jinja2 b/content/shell/android/shell_apk/AndroidManifest.xml.jinja2
index 2722488..d89c3906 100644
--- a/content/shell/android/shell_apk/AndroidManifest.xml.jinja2
+++ b/content/shell/android/shell_apk/AndroidManifest.xml.jinja2
@@ -24,7 +24,7 @@
 
     <application android:name="org.chromium.content_shell_apk.ContentShellApplication"
             android:icon="@mipmap/app_icon"
-            android:zygotePreloadName="org.chromium.content.app.ZygotePreload"
+            android:zygotePreloadName="org.chromium.content_public.app.ZygotePreload"
             android:label="{% block application_label %}Content Shell{% endblock %}">
         <activity android:name="org.chromium.content_shell_apk.ContentShellActivity"
                   android:launchMode="singleTask"
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 4587fb8..582faee 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -616,15 +616,16 @@
 }
 
 void ShellContentBrowserClient::SetUpFieldTrials() {
-  if (!base::FieldTrialList::GetInstance()) {
-    // Note: This is intentionally leaked since it needs to live for the
-    // duration of the browser process and there's no benefit in cleaning it up
-    // at exit.
-    base::FieldTrialList* leaked_field_trial_list =
-        new base::FieldTrialList(nullptr);
-    ANNOTATE_LEAKING_OBJECT_PTR(leaked_field_trial_list);
-    ignore_result(leaked_field_trial_list);
-  }
+  metrics::TestEnabledStateProvider enabled_state_provider(/*consent=*/false,
+                                                           /*enabled=*/false);
+  base::FilePath path;
+  base::PathService::Get(SHELL_DIR_USER_DATA, &path);
+  std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager =
+      metrics::MetricsStateManager::Create(
+          local_state_.get(), &enabled_state_provider, std::wstring(),
+          path.AppendASCII("Local State"));
+  metrics_state_manager->InstantiateFieldTrialList(
+      cc::switches::kEnableGpuBenchmarking);
 
   std::vector<std::string> variation_ids;
   auto feature_list = std::make_unique<base::FeatureList>();
@@ -647,22 +648,13 @@
           /*signature_verification_enabled=*/true),
       variations::UIStringOverrider());
 
-  metrics::TestEnabledStateProvider enabled_state_provider(/*consent=*/false,
-                                                           /*enabled=*/false);
-  base::FilePath path;
-  base::PathService::Get(SHELL_DIR_USER_DATA, &path);
-  std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager =
-      metrics::MetricsStateManager::Create(
-          local_state_.get(), &enabled_state_provider, std::wstring(),
-          path.AppendASCII("Local State"));
   variations::SafeSeedManager safe_seed_manager(local_state_.get());
 
   // Since this is a test-only code path, some arguments to SetupFieldTrials are
   // null.
   // TODO(crbug/1248066): Consider passing a low entropy provider and source.
   field_trial_creator.SetupFieldTrials(
-      cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
-      switches::kDisableFeatures, variation_ids,
+      variation_ids,
       content::GetSwitchDependentFeatureOverrides(
           *base::CommandLine::ForCurrentProcess()),
       /*low_entropy_provider=*/nullptr, std::move(feature_list),
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 7112272..221c7dd 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -1869,6 +1869,7 @@
     "../browser/accessibility/touch_passthrough_manager_unittest.cc",
     "../browser/aggregation_service/aggregatable_report_sender_unittest.cc",
     "../browser/aggregation_service/aggregation_service_key_fetcher_unittest.cc",
+    "../browser/aggregation_service/aggregation_service_network_fetcher_impl_unittest.cc",
     "../browser/aggregation_service/aggregation_service_storage_sql_unittest.cc",
     "../browser/aggregation_service/public_key_parsing_utils_unittest.cc",
     "../browser/background_fetch/background_fetch_cross_origin_filter_unittest.cc",
diff --git a/content/test/test_aggregation_service_impl.cc b/content/test/test_aggregation_service_impl.cc
index e84ac72f..2d83f49 100644
--- a/content/test/test_aggregation_service_impl.cc
+++ b/content/test/test_aggregation_service_impl.cc
@@ -60,11 +60,11 @@
     return;
   }
 
-  PublicKeysForOrigin keys(origin,
-                           aggregation_service::GetPublicKeys(*value_ptr));
+  PublicKeyset keyset(aggregation_service::GetPublicKeys(*value_ptr),
+                      /*fetch_time=*/clock_.Now(),
+                      /*expiry_time=*/base::Time::Max());
   storage_.AsyncCall(&AggregationServiceKeyStorage::SetPublicKeys)
-      .WithArgs(std::move(keys), /*fetch_time=*/clock_.Now(),
-                /*expiry_time=*/base::Time::Max())
+      .WithArgs(origin, std::move(keyset))
       .Then(base::BindOnce(std::move(callback), true));
 }
 
@@ -90,7 +90,7 @@
 
 void TestAggregationServiceImpl::GetPublicKeys(
     const url::Origin& origin,
-    base::OnceCallback<void(PublicKeysForOrigin)> callback) const {
+    base::OnceCallback<void(std::vector<PublicKey>)> callback) const {
   storage_.AsyncCall(&AggregationServiceKeyStorage::GetPublicKeys)
       .WithArgs(origin)
       .Then(std::move(callback));
diff --git a/content/test/test_aggregation_service_impl.h b/content/test/test_aggregation_service_impl.h
index e9fa219c..0ffc79f 100644
--- a/content/test/test_aggregation_service_impl.h
+++ b/content/test/test_aggregation_service_impl.h
@@ -6,6 +6,7 @@
 #define CONTENT_TEST_TEST_AGGREGATION_SERVICE_IMPL_H_
 
 #include <memory>
+#include <vector>
 
 #include "base/callback_forward.h"
 #include "base/threading/sequence_bound.h"
@@ -25,7 +26,7 @@
 
 class AggregatableReportSender;
 
-struct PublicKeysForOrigin;
+struct PublicKey;
 
 // Implementation class of a test aggregation service.
 class TestAggregationServiceImpl : public AggregatableReportManager,
@@ -55,7 +56,7 @@
 
   void GetPublicKeys(
       const url::Origin& origin,
-      base::OnceCallback<void(PublicKeysForOrigin)> callback) const;
+      base::OnceCallback<void(std::vector<PublicKey>)> callback) const;
 
  private:
   const base::Clock& clock_;
diff --git a/content/test/test_aggregation_service_impl_unittest.cc b/content/test/test_aggregation_service_impl_unittest.cc
index a5f86d9..7164796 100644
--- a/content/test/test_aggregation_service_impl_unittest.cc
+++ b/content/test/test_aggregation_service_impl_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 #include <string>
+#include <vector>
 
 #include "base/run_loop.h"
 #include "base/test/bind.h"
@@ -33,7 +34,7 @@
 TEST_F(TestAggregationServiceImplTest, SetPublicKeys) {
   std::string json_string = R"(
         {
-            "version" : "v1",
+            "version" : "",
             "keys" : [
                 {
                     "id" : "abcd",
@@ -52,10 +53,10 @@
 
   base::RunLoop run_loop;
   impl_->GetPublicKeys(
-      origin, base::BindLambdaForTesting([&](PublicKeysForOrigin keys) {
+      origin, base::BindLambdaForTesting([&](std::vector<PublicKey> keys) {
         EXPECT_TRUE(content::aggregation_service::PublicKeysEqual(
             {content::PublicKey(/*id=*/"abcd", /*key=*/kABCD1234AsBytes)},
-            keys.keys));
+            keys));
         run_loop.Quit();
       }));
   run_loop.Run();
diff --git a/device/base/device_info_query_win.h b/device/base/device_info_query_win.h
index 02baf03..d0a0fd6 100644
--- a/device/base/device_info_query_win.h
+++ b/device/base/device_info_query_win.h
@@ -21,6 +21,10 @@
 class DEVICE_BASE_EXPORT DeviceInfoQueryWin {
  public:
   DeviceInfoQueryWin();
+
+  DeviceInfoQueryWin(const DeviceInfoQueryWin&) = delete;
+  DeviceInfoQueryWin& operator=(const DeviceInfoQueryWin&) = delete;
+
   ~DeviceInfoQueryWin();
 
   // Add a device to |device_info_list_| using its |device_path| so that
@@ -41,8 +45,6 @@
   HDEVINFO device_info_list_ = INVALID_HANDLE_VALUE;
   // When device_info_data_.cbSize != 0, |device_info_data_| is valid.
   SP_DEVINFO_DATA device_info_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeviceInfoQueryWin);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/adapter.h b/device/bluetooth/adapter.h
index e6618ef..ab5fdd7 100644
--- a/device/bluetooth/adapter.h
+++ b/device/bluetooth/adapter.h
@@ -31,6 +31,10 @@
                 public device::BluetoothAdapter::Observer {
  public:
   explicit Adapter(scoped_refptr<device::BluetoothAdapter> adapter);
+
+  Adapter(const Adapter&) = delete;
+  Adapter& operator=(const Adapter&) = delete;
+
   ~Adapter() override;
 
   // mojom::Adapter overrides:
@@ -164,8 +168,6 @@
   int next_request_id_ = 0;
 
   base::WeakPtrFactory<Adapter> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(Adapter);
 };
 
 }  // namespace bluetooth
diff --git a/device/bluetooth/bluetooth_adapter_factory.h b/device/bluetooth/bluetooth_adapter_factory.h
index 11f51ab..df071fae 100644
--- a/device/bluetooth/bluetooth_adapter_factory.h
+++ b/device/bluetooth/bluetooth_adapter_factory.h
@@ -99,6 +99,10 @@
   class DEVICE_BLUETOOTH_EXPORT GlobalValuesForTesting {
    public:
     GlobalValuesForTesting();
+
+    GlobalValuesForTesting(const GlobalValuesForTesting&) = delete;
+    GlobalValuesForTesting& operator=(const GlobalValuesForTesting&) = delete;
+
     ~GlobalValuesForTesting();
 
     void SetLESupported(bool supported) { le_supported_ = supported; }
@@ -111,7 +115,6 @@
     bool le_supported_ = false;
 
     base::WeakPtrFactory<GlobalValuesForTesting> weak_ptr_factory_{this};
-    DISALLOW_COPY_AND_ASSIGN(GlobalValuesForTesting);
   };
 
   // Returns an object that clients can use to control the return values
diff --git a/device/bluetooth/bluetooth_advertisement.h b/device/bluetooth/bluetooth_advertisement.h
index a11e82bd..4ed3e87 100644
--- a/device/bluetooth/bluetooth_advertisement.h
+++ b/device/bluetooth/bluetooth_advertisement.h
@@ -68,6 +68,10 @@
   class DEVICE_BLUETOOTH_EXPORT Data {
    public:
     explicit Data(AdvertisementType type);
+
+    Data(const Data&) = delete;
+    Data& operator=(const Data&) = delete;
+
     ~Data();
 
     AdvertisementType type() { return type_; }
@@ -119,8 +123,6 @@
     std::unique_ptr<ServiceData> service_data_;
     std::unique_ptr<ScanResponseData> scan_response_data_;
     bool include_tx_power_;
-
-    DISALLOW_COPY_AND_ASSIGN(Data);
   };
 
   // Interface for observing changes to this advertisement.
diff --git a/device/bluetooth/bluetooth_channel_mac.h b/device/bluetooth/bluetooth_channel_mac.h
index b1ecee1..12331a36 100644
--- a/device/bluetooth/bluetooth_channel_mac.h
+++ b/device/bluetooth/bluetooth_channel_mac.h
@@ -22,6 +22,10 @@
 class BluetoothChannelMac {
  public:
   BluetoothChannelMac();
+
+  BluetoothChannelMac(const BluetoothChannelMac&) = delete;
+  BluetoothChannelMac& operator=(const BluetoothChannelMac&) = delete;
+
   virtual ~BluetoothChannelMac();
 
   // Sets the channel's owning socket to |socket|. Should only be called if the
@@ -56,8 +60,6 @@
  private:
   // The socket that owns |this|.
   BluetoothSocketMac* socket_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothChannelMac);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_classic_device_mac.h b/device/bluetooth/bluetooth_classic_device_mac.h
index 05208ee..d95122e 100644
--- a/device/bluetooth/bluetooth_classic_device_mac.h
+++ b/device/bluetooth/bluetooth_classic_device_mac.h
@@ -27,6 +27,11 @@
  public:
   explicit BluetoothClassicDeviceMac(BluetoothAdapterMac* adapter,
                                      IOBluetoothDevice* device);
+
+  BluetoothClassicDeviceMac(const BluetoothClassicDeviceMac&) = delete;
+  BluetoothClassicDeviceMac& operator=(const BluetoothClassicDeviceMac&) =
+      delete;
+
   ~BluetoothClassicDeviceMac() override;
 
   // BluetoothDevice override
@@ -94,8 +99,6 @@
       BluetoothHCITransmitPowerLevelType power_level_type) const;
 
   base::scoped_nsobject<IOBluetoothDevice> device_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothClassicDeviceMac);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h
index 417f595f..1a65264 100644
--- a/device/bluetooth/bluetooth_device.h
+++ b/device/bluetooth/bluetooth_device.h
@@ -203,6 +203,9 @@
     virtual void AuthorizePairing(BluetoothDevice* device) = 0;
   };
 
+  BluetoothDevice(const BluetoothDevice&) = delete;
+  BluetoothDevice& operator=(const BluetoothDevice&) = delete;
+
   virtual ~BluetoothDevice();
 
   // Clamps numbers less than -128 to -128 and numbers greater than 127 to 127.
@@ -783,8 +786,6 @@
   // Mojo service, this field will be moved to BluetoothDeviceInfo.
   absl::optional<uint8_t> battery_percentage_;
 #endif
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDevice);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_device_android.h b/device/bluetooth/bluetooth_device_android.h
index de413a6..def7c5e 100644
--- a/device/bluetooth/bluetooth_device_android.h
+++ b/device/bluetooth/bluetooth_device_android.h
@@ -37,6 +37,9 @@
       const base::android::JavaRef<jobject>&
           bluetooth_device_wrapper);  // Java Type: bluetoothDeviceWrapper
 
+  BluetoothDeviceAndroid(const BluetoothDeviceAndroid&) = delete;
+  BluetoothDeviceAndroid& operator=(const BluetoothDeviceAndroid&) = delete;
+
   ~BluetoothDeviceAndroid() override;
 
   // Returns the associated ChromeBluetoothDevice Java object.
@@ -123,8 +126,6 @@
   base::android::ScopedJavaGlobalRef<jobject> j_device_;
 
   bool gatt_connected_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceAndroid);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h
index 31873d6..0f16a02 100644
--- a/device/bluetooth/bluetooth_device_mac.h
+++ b/device/bluetooth/bluetooth_device_mac.h
@@ -17,6 +17,9 @@
 
 class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceMac : public BluetoothDevice {
  public:
+  BluetoothDeviceMac(const BluetoothDeviceMac&) = delete;
+  BluetoothDeviceMac& operator=(const BluetoothDeviceMac&) = delete;
+
   ~BluetoothDeviceMac() override;
 
   // Converts between ConnectErrorCode and NSError.
@@ -31,8 +34,6 @@
 
  protected:
   BluetoothDeviceMac(BluetoothAdapterMac* adapter);
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceMac);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h
index 0df3dcf..007da9d 100644
--- a/device/bluetooth/bluetooth_device_win.h
+++ b/device/bluetooth/bluetooth_device_win.h
@@ -36,6 +36,10 @@
       const BluetoothTaskManagerWin::DeviceState& device_state,
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner,
       scoped_refptr<BluetoothSocketThread> socket_thread);
+
+  BluetoothDeviceWin(const BluetoothDeviceWin&) = delete;
+  BluetoothDeviceWin& operator=(const BluetoothDeviceWin&) = delete;
+
   ~BluetoothDeviceWin() override;
 
   // BluetoothDevice override
@@ -166,8 +170,6 @@
   // BluetoothRemoteGattServiceWin instance.
   std::set<std::pair<BluetoothUUID, uint16_t>>
       discovery_completed_included_services_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceWin);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_device_winrt.h b/device/bluetooth/bluetooth_device_winrt.h
index daa33c24..cc29e221 100644
--- a/device/bluetooth/bluetooth_device_winrt.h
+++ b/device/bluetooth/bluetooth_device_winrt.h
@@ -43,6 +43,10 @@
   static constexpr uint8_t k128BitServiceDataSection = 0x21;
 
   BluetoothDeviceWinrt(BluetoothAdapterWinrt* adapter, uint64_t raw_address);
+
+  BluetoothDeviceWinrt(const BluetoothDeviceWinrt&) = delete;
+  BluetoothDeviceWinrt& operator=(const BluetoothDeviceWinrt&) = delete;
+
   ~BluetoothDeviceWinrt() override;
 
   // BluetoothDevice:
@@ -192,8 +196,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothDeviceWinrt> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_discovery_filter.h b/device/bluetooth/bluetooth_discovery_filter.h
index 20e58be..e274bf8 100644
--- a/device/bluetooth/bluetooth_discovery_filter.h
+++ b/device/bluetooth/bluetooth_discovery_filter.h
@@ -51,6 +51,10 @@
  public:
   BluetoothDiscoveryFilter();
   BluetoothDiscoveryFilter(BluetoothTransport transport);
+
+  BluetoothDiscoveryFilter(const BluetoothDiscoveryFilter&) = delete;
+  BluetoothDiscoveryFilter& operator=(const BluetoothDiscoveryFilter&) = delete;
+
   ~BluetoothDiscoveryFilter();
 
   struct DEVICE_BLUETOOTH_EXPORT DeviceInfoFilter {
@@ -106,8 +110,6 @@
   absl::optional<uint16_t> pathloss_;
   BluetoothTransport transport_;
   base::flat_set<DeviceInfoFilter> device_filters_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoveryFilter);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_discovery_manager_mac.mm b/device/bluetooth/bluetooth_discovery_manager_mac.mm
index d05ff3c..c7849bc 100644
--- a/device/bluetooth/bluetooth_discovery_manager_mac.mm
+++ b/device/bluetooth/bluetooth_discovery_manager_mac.mm
@@ -46,6 +46,11 @@
         inquiry_([[IOBluetoothDeviceInquiry alloc]
             initWithDelegate:inquiry_delegate_]) {}
 
+  BluetoothDiscoveryManagerMacClassic(
+      const BluetoothDiscoveryManagerMacClassic&) = delete;
+  BluetoothDiscoveryManagerMacClassic& operator=(
+      const BluetoothDiscoveryManagerMacClassic&) = delete;
+
   ~BluetoothDiscoveryManagerMacClassic() override {}
 
   // BluetoothDiscoveryManagerMac override.
@@ -180,8 +185,6 @@
   // Objective-C objects for running and tracking device inquiry.
   base::scoped_nsobject<BluetoothDeviceInquiryDelegate> inquiry_delegate_;
   base::scoped_nsobject<IOBluetoothDeviceInquiry> inquiry_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoveryManagerMacClassic);
 };
 
 BluetoothDiscoveryManagerMac::BluetoothDiscoveryManagerMac(
diff --git a/device/bluetooth/bluetooth_discovery_session.h b/device/bluetooth/bluetooth_discovery_session.h
index 62aa3cbb..bb2eb746 100644
--- a/device/bluetooth/bluetooth_discovery_session.h
+++ b/device/bluetooth/bluetooth_discovery_session.h
@@ -47,6 +47,10 @@
     INACTIVE
   };
 
+  BluetoothDiscoverySession(const BluetoothDiscoverySession&) = delete;
+  BluetoothDiscoverySession& operator=(const BluetoothDiscoverySession&) =
+      delete;
+
   // Terminates the discovery session. If this is the last active discovery
   // session, a call to the underlying system to stop device discovery is made.
   // Users may call BluetoothDiscoverySession::Stop() if they need to observe
@@ -127,8 +131,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothDiscoverySession> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDiscoverySession);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_gatt_connection.h b/device/bluetooth/bluetooth_gatt_connection.h
index e616a11..6b4c708 100644
--- a/device/bluetooth/bluetooth_gatt_connection.h
+++ b/device/bluetooth/bluetooth_gatt_connection.h
@@ -27,6 +27,9 @@
   BluetoothGattConnection(scoped_refptr<device::BluetoothAdapter> adapter,
                           const std::string& device_address);
 
+  BluetoothGattConnection(const BluetoothGattConnection&) = delete;
+  BluetoothGattConnection& operator=(const BluetoothGattConnection&) = delete;
+
   // Destructor automatically closes this GATT connection. If this is the last
   // remaining GATT connection and this results in a call to the OS, that call
   // may not always succeed. Users can make an explicit call to
@@ -65,8 +68,6 @@
 
  private:
   bool owns_reference_for_connection_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattConnection);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_gatt_discoverer_winrt.h b/device/bluetooth/bluetooth_gatt_discoverer_winrt.h
index ec66a50..7412a5dd 100644
--- a/device/bluetooth/bluetooth_gatt_discoverer_winrt.h
+++ b/device/bluetooth/bluetooth_gatt_discoverer_winrt.h
@@ -48,6 +48,11 @@
       Microsoft::WRL::ComPtr<
           ABI::Windows::Devices::Bluetooth::IBluetoothLEDevice> ble_device,
       absl::optional<BluetoothUUID> service_uuid);
+
+  BluetoothGattDiscovererWinrt(const BluetoothGattDiscovererWinrt&) = delete;
+  BluetoothGattDiscovererWinrt& operator=(const BluetoothGattDiscovererWinrt&) =
+      delete;
+
   ~BluetoothGattDiscovererWinrt();
 
   // Note: In order to avoid running |callback| multiple times on errors,
@@ -106,8 +111,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattDiscovererWinrt> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDiscovererWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_gatt_notify_session.h b/device/bluetooth/bluetooth_gatt_notify_session.h
index 45119f9..2724af85 100644
--- a/device/bluetooth/bluetooth_gatt_notify_session.h
+++ b/device/bluetooth/bluetooth_gatt_notify_session.h
@@ -25,6 +25,10 @@
   explicit BluetoothGattNotifySession(
       base::WeakPtr<BluetoothRemoteGattCharacteristic> characteristic);
 
+  BluetoothGattNotifySession(const BluetoothGattNotifySession&) = delete;
+  BluetoothGattNotifySession& operator=(const BluetoothGattNotifySession&) =
+      delete;
+
   // Destructor automatically stops this session.
   virtual ~BluetoothGattNotifySession();
 
@@ -51,8 +55,6 @@
   base::WeakPtr<BluetoothRemoteGattCharacteristic> characteristic_;
   std::string characteristic_id_;
   bool active_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattNotifySession);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_gatt_service.h b/device/bluetooth/bluetooth_gatt_service.h
index 7e3586f..3db9f06 100644
--- a/device/bluetooth/bluetooth_gatt_service.h
+++ b/device/bluetooth/bluetooth_gatt_service.h
@@ -53,13 +53,13 @@
   // services.
   virtual bool IsPrimary() const = 0;
 
+  BluetoothGattService(const BluetoothGattService&) = delete;
+  BluetoothGattService& operator=(const BluetoothGattService&) = delete;
+
   virtual ~BluetoothGattService();
 
  protected:
   BluetoothGattService();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattService);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_l2cap_channel_mac.h b/device/bluetooth/bluetooth_l2cap_channel_mac.h
index 5fe6194..f8e6fbaa 100644
--- a/device/bluetooth/bluetooth_l2cap_channel_mac.h
+++ b/device/bluetooth/bluetooth_l2cap_channel_mac.h
@@ -27,6 +27,10 @@
   // NOTE: The |channel| is expected to already be retained.
   BluetoothL2capChannelMac(BluetoothSocketMac* socket,
                            IOBluetoothL2CAPChannel* channel);
+
+  BluetoothL2capChannelMac(const BluetoothL2capChannelMac&) = delete;
+  BluetoothL2capChannelMac& operator=(const BluetoothL2capChannelMac&) = delete;
+
   ~BluetoothL2capChannelMac() override;
 
   // Opens a new L2CAP channel with Channel ID |channel_id| to the target
@@ -61,8 +65,6 @@
 
   // The delegate for the native channel.
   base::scoped_nsobject<BluetoothL2capChannelDelegate> delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothL2capChannelMac);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_low_energy_advertisement_manager_mac.h b/device/bluetooth/bluetooth_low_energy_advertisement_manager_mac.h
index 408c0344..f2d937e 100644
--- a/device/bluetooth/bluetooth_low_energy_advertisement_manager_mac.h
+++ b/device/bluetooth/bluetooth_low_energy_advertisement_manager_mac.h
@@ -18,6 +18,12 @@
 class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyAdvertisementManagerMac {
  public:
   BluetoothLowEnergyAdvertisementManagerMac();
+
+  BluetoothLowEnergyAdvertisementManagerMac(
+      const BluetoothLowEnergyAdvertisementManagerMac&) = delete;
+  BluetoothLowEnergyAdvertisementManagerMac& operator=(
+      const BluetoothLowEnergyAdvertisementManagerMac&) = delete;
+
   ~BluetoothLowEnergyAdvertisementManagerMac();
 
   // Initializes the advertisement manager.
@@ -52,8 +58,6 @@
   CBPeripheralManager* peripheral_manager_;
 
   scoped_refptr<BluetoothAdvertisementMac> active_advertisement_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyAdvertisementManagerMac);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_low_energy_device_mac.h b/device/bluetooth/bluetooth_low_energy_device_mac.h
index 54116b3..f6234d5 100644
--- a/device/bluetooth/bluetooth_low_energy_device_mac.h
+++ b/device/bluetooth/bluetooth_low_energy_device_mac.h
@@ -36,6 +36,11 @@
  public:
   BluetoothLowEnergyDeviceMac(BluetoothAdapterMac* adapter,
                               CBPeripheral* peripheral);
+
+  BluetoothLowEnergyDeviceMac(const BluetoothLowEnergyDeviceMac&) = delete;
+  BluetoothLowEnergyDeviceMac& operator=(const BluetoothLowEnergyDeviceMac&) =
+      delete;
+
   ~BluetoothLowEnergyDeviceMac() override;
 
   // BluetoothDevice overrides.
@@ -168,8 +173,6 @@
   // decreases each time DidDiscoverPrimaryServices() is called. Once the
   // value is set to 0, characteristics and properties are discovered.
   int discovery_pending_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothLowEnergyDeviceMac);
 };
 
 // Stream operator for logging.
diff --git a/device/bluetooth/bluetooth_low_energy_win.h b/device/bluetooth/bluetooth_low_energy_win.h
index 0749f9d..1df3e4d5 100644
--- a/device/bluetooth/bluetooth_low_energy_win.h
+++ b/device/bluetooth/bluetooth_low_energy_win.h
@@ -47,6 +47,11 @@
       DWORD property_type,
       std::unique_ptr<uint8_t[]> value,
       size_t value_size);
+
+  DeviceRegistryPropertyValue(const DeviceRegistryPropertyValue&) = delete;
+  DeviceRegistryPropertyValue& operator=(const DeviceRegistryPropertyValue&) =
+      delete;
+
   ~DeviceRegistryPropertyValue();
 
   // Returns the vaue type a REG_xxx value (e.g. REG_SZ, REG_DWORD, ...)
@@ -61,8 +66,6 @@
 
   DWORD property_type_;
   std::unique_ptr<uint8_t[]> value_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeviceRegistryPropertyValue);
 };
 
 // Represents the value associated to a DEVPROPKEY.
@@ -75,6 +78,10 @@
   DevicePropertyValue(DEVPROPTYPE property_type,
                       std::unique_ptr<uint8_t[]> value,
                       size_t value_size);
+
+  DevicePropertyValue(const DevicePropertyValue&) = delete;
+  DevicePropertyValue& operator=(const DevicePropertyValue&) = delete;
+
   ~DevicePropertyValue();
 
   DEVPROPTYPE property_type() const { return property_type_; }
@@ -85,8 +92,6 @@
   DEVPROPTYPE property_type_;
   std::unique_ptr<uint8_t[]> value_;
   size_t value_size_;
-
-  DISALLOW_COPY_AND_ASSIGN(DevicePropertyValue);
 };
 
 struct DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyServiceInfo {
diff --git a/device/bluetooth/bluetooth_pairing_winrt.h b/device/bluetooth/bluetooth_pairing_winrt.h
index 2108ebf..bba68cf 100644
--- a/device/bluetooth/bluetooth_pairing_winrt.h
+++ b/device/bluetooth/bluetooth_pairing_winrt.h
@@ -36,6 +36,9 @@
           custom_pairing,
       ConnectCallback callback);
 
+  BluetoothPairingWinrt(const BluetoothPairingWinrt&) = delete;
+  BluetoothPairingWinrt& operator=(const BluetoothPairingWinrt&) = delete;
+
   ~BluetoothPairingWinrt();
 
   // Initiates the pairing procedure.
@@ -92,8 +95,6 @@
   SEQUENCE_CHECKER(sequence_checker_);
 
   base::WeakPtrFactory<BluetoothPairingWinrt> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothPairingWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic.h b/device/bluetooth/bluetooth_remote_gatt_characteristic.h
index a0055929..5700e68 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic.h
@@ -63,6 +63,11 @@
   using NotifySessionCallback =
       base::OnceCallback<void(std::unique_ptr<BluetoothGattNotifySession>)>;
 
+  BluetoothRemoteGattCharacteristic(const BluetoothRemoteGattCharacteristic&) =
+      delete;
+  BluetoothRemoteGattCharacteristic& operator=(
+      const BluetoothRemoteGattCharacteristic&) = delete;
+
   ~BluetoothRemoteGattCharacteristic() override;
 
   // Returns the value of the characteristic. For remote characteristics, this
@@ -315,8 +320,6 @@
 
   base::WeakPtrFactory<BluetoothRemoteGattCharacteristic> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristic);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
index 89f5514f..b37ee7d 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.h
@@ -46,6 +46,11 @@
       const base::android::JavaRef<
           jobject>& /* ChromeBluetoothDevice */ chrome_bluetooth_device);
 
+  BluetoothRemoteGattCharacteristicAndroid(
+      const BluetoothRemoteGattCharacteristicAndroid&) = delete;
+  BluetoothRemoteGattCharacteristicAndroid& operator=(
+      const BluetoothRemoteGattCharacteristicAndroid&) = delete;
+
   ~BluetoothRemoteGattCharacteristicAndroid() override;
 
   // Returns the associated ChromeBluetoothRemoteGattCharacteristic Java object.
@@ -151,8 +156,6 @@
   ErrorCallback write_error_callback_;
 
   std::vector<uint8_t> value_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicAndroid);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h
index 60164dd..f8428be 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_mac.h
@@ -29,6 +29,12 @@
   BluetoothRemoteGattCharacteristicMac(
       BluetoothRemoteGattServiceMac* gatt_service,
       CBCharacteristic* cb_characteristic);
+
+  BluetoothRemoteGattCharacteristicMac(
+      const BluetoothRemoteGattCharacteristicMac&) = delete;
+  BluetoothRemoteGattCharacteristicMac& operator=(
+      const BluetoothRemoteGattCharacteristicMac&) = delete;
+
   ~BluetoothRemoteGattCharacteristicMac() override;
 
   // Override BluetoothGattCharacteristic methods.
@@ -139,8 +145,6 @@
   PendingNotifyCallbacks unsubscribe_from_notification_callbacks_;
 
   base::WeakPtrFactory<BluetoothRemoteGattCharacteristicMac> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicMac);
 };
 
 // Stream operator for logging.
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h
index 027b82bd..affe153 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_win.h
@@ -32,6 +32,12 @@
       BluetoothRemoteGattServiceWin* parent_service,
       BTH_LE_GATT_CHARACTERISTIC* characteristic_info,
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
+
+  BluetoothRemoteGattCharacteristicWin(
+      const BluetoothRemoteGattCharacteristicWin&) = delete;
+  BluetoothRemoteGattCharacteristicWin& operator=(
+      const BluetoothRemoteGattCharacteristicWin&) = delete;
+
   ~BluetoothRemoteGattCharacteristicWin() override;
 
   // Override BluetoothRemoteGattCharacteristic interfaces.
@@ -130,7 +136,6 @@
 
   base::WeakPtrFactory<BluetoothRemoteGattCharacteristicWin> weak_ptr_factory_{
       this};
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicWin);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h
index d700c61..522bd0b5 100644
--- a/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h
+++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_winrt.h
@@ -34,6 +34,12 @@
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                  GenericAttributeProfile::IGattCharacteristic>
           characteristic);
+
+  BluetoothRemoteGattCharacteristicWinrt(
+      const BluetoothRemoteGattCharacteristicWinrt&) = delete;
+  BluetoothRemoteGattCharacteristicWinrt& operator=(
+      const BluetoothRemoteGattCharacteristicWinrt&) = delete;
+
   ~BluetoothRemoteGattCharacteristicWinrt() override;
 
   // BluetoothGattCharacteristic:
@@ -145,8 +151,6 @@
 
   base::WeakPtrFactory<BluetoothRemoteGattCharacteristicWinrt>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor.h b/device/bluetooth/bluetooth_remote_gatt_descriptor.h
index 7925e3a..84857cd 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor.h
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor.h
@@ -30,6 +30,10 @@
 class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattDescriptor
     : public virtual BluetoothGattDescriptor {
  public:
+  BluetoothRemoteGattDescriptor(const BluetoothRemoteGattDescriptor&) = delete;
+  BluetoothRemoteGattDescriptor& operator=(
+      const BluetoothRemoteGattDescriptor&) = delete;
+
   ~BluetoothRemoteGattDescriptor() override;
 
   // The ValueCallback is used to return the value of a remote characteristic
@@ -67,9 +71,6 @@
 
  protected:
   BluetoothRemoteGattDescriptor();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptor);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_android.h b/device/bluetooth/bluetooth_remote_gatt_descriptor_android.h
index de7d019..98ae041d 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_android.h
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_android.h
@@ -35,6 +35,11 @@
       const base::android::JavaRef<
           jobject>& /* chromeBluetoothDevice */ chrome_bluetooth_device);
 
+  BluetoothRemoteGattDescriptorAndroid(
+      const BluetoothRemoteGattDescriptorAndroid&) = delete;
+  BluetoothRemoteGattDescriptorAndroid& operator=(
+      const BluetoothRemoteGattDescriptorAndroid&) = delete;
+
   ~BluetoothRemoteGattDescriptorAndroid() override;
 
   // Returns the associated ChromeBluetoothRemoteGattDescriptor Java object.
@@ -83,8 +88,6 @@
   ErrorCallback write_error_callback_;
 
   std::vector<uint8_t> value_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorAndroid);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_win.h b/device/bluetooth/bluetooth_remote_gatt_descriptor_win.h
index f99cde3..579afbd 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_win.h
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_win.h
@@ -29,6 +29,12 @@
       BluetoothRemoteGattCharacteristicWin* parent_characteristic,
       BTH_LE_GATT_DESCRIPTOR* descriptor_info,
       scoped_refptr<base::SequencedTaskRunner>& ui_task_runner);
+
+  BluetoothRemoteGattDescriptorWin(const BluetoothRemoteGattDescriptorWin&) =
+      delete;
+  BluetoothRemoteGattDescriptorWin& operator=(
+      const BluetoothRemoteGattDescriptorWin&) = delete;
+
   ~BluetoothRemoteGattDescriptorWin() override;
 
   // Override BluetoothRemoteGattDescriptor interfaces.
@@ -62,7 +68,6 @@
 
   base::WeakPtrFactory<BluetoothRemoteGattDescriptorWin> weak_ptr_factory_{
       this};
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorWin);
 };
 
 }  // namespace device.
diff --git a/device/bluetooth/bluetooth_remote_gatt_descriptor_winrt.h b/device/bluetooth/bluetooth_remote_gatt_descriptor_winrt.h
index 049171ea..ea810265 100644
--- a/device/bluetooth/bluetooth_remote_gatt_descriptor_winrt.h
+++ b/device/bluetooth/bluetooth_remote_gatt_descriptor_winrt.h
@@ -32,6 +32,12 @@
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                  GenericAttributeProfile::IGattDescriptor>
           descriptor);
+
+  BluetoothRemoteGattDescriptorWinrt(
+      const BluetoothRemoteGattDescriptorWinrt&) = delete;
+  BluetoothRemoteGattDescriptorWinrt& operator=(
+      const BluetoothRemoteGattDescriptorWinrt&) = delete;
+
   ~BluetoothRemoteGattDescriptorWinrt() override;
 
   // BluetoothGattDescriptor:
@@ -90,8 +96,6 @@
 
   base::WeakPtrFactory<BluetoothRemoteGattDescriptorWinrt> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_service.h b/device/bluetooth/bluetooth_remote_gatt_service.h
index 97c00b1..e32a6a5 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service.h
@@ -34,6 +34,10 @@
 class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattService
     : public virtual BluetoothGattService {
  public:
+  BluetoothRemoteGattService(const BluetoothRemoteGattService&) = delete;
+  BluetoothRemoteGattService& operator=(const BluetoothRemoteGattService&) =
+      delete;
+
   ~BluetoothRemoteGattService() override;
 
   // Returns the BluetoothDevice that this GATT service was received from, which
@@ -79,8 +83,6 @@
  private:
   // Is true if all the characteristics have been discovered.
   bool discovery_complete_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattService);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_android.h b/device/bluetooth/bluetooth_remote_gatt_service_android.h
index cf731ba..9a9d839 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_android.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_android.h
@@ -42,6 +42,11 @@
       const base::android::JavaRef<jobject>&
           chrome_bluetooth_device);  // ChromeBluetoothDevice
 
+  BluetoothRemoteGattServiceAndroid(const BluetoothRemoteGattServiceAndroid&) =
+      delete;
+  BluetoothRemoteGattServiceAndroid& operator=(
+      const BluetoothRemoteGattServiceAndroid&) = delete;
+
   ~BluetoothRemoteGattServiceAndroid() override;
 
   // Returns the associated ChromeBluetoothRemoteGattService Java object.
@@ -106,8 +111,6 @@
 
   // Adapter unique instance ID.
   std::string instance_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceAndroid);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_mac.h b/device/bluetooth/bluetooth_remote_gatt_service_mac.h
index 20bfd73..17d1af6 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_mac.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_mac.h
@@ -33,6 +33,11 @@
       BluetoothLowEnergyDeviceMac* bluetooth_device_mac,
       CBService* service,
       bool is_primary);
+
+  BluetoothRemoteGattServiceMac(const BluetoothRemoteGattServiceMac&) = delete;
+  BluetoothRemoteGattServiceMac& operator=(
+      const BluetoothRemoteGattServiceMac&) = delete;
+
   ~BluetoothRemoteGattServiceMac() override;
 
   // BluetoothRemoteGattService override.
@@ -84,8 +89,6 @@
   // Increased each time DiscoverCharacteristics() is called. And decreased when
   // DidDiscoverCharacteristics() is called.
   int discovery_pending_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceMac);
 };
 
 // Stream operator for logging.
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_win.h b/device/bluetooth/bluetooth_remote_gatt_service_win.h
index 34bf2e3..fb341cb 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_win.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_win.h
@@ -36,6 +36,11 @@
       bool is_primary,
       BluetoothRemoteGattServiceWin* parent_service,
       scoped_refptr<base::SequencedTaskRunner> ui_task_runner);
+
+  BluetoothRemoteGattServiceWin(const BluetoothRemoteGattServiceWin&) = delete;
+  BluetoothRemoteGattServiceWin& operator=(
+      const BluetoothRemoteGattServiceWin&) = delete;
+
   ~BluetoothRemoteGattServiceWin() override;
 
   // Override BluetoothRemoteGattService interfaces.
@@ -110,7 +115,6 @@
   int discovery_pending_count_ = 0;
 
   base::WeakPtrFactory<BluetoothRemoteGattServiceWin> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceWin);
 };
 
 }  // namespace device.
diff --git a/device/bluetooth/bluetooth_remote_gatt_service_winrt.h b/device/bluetooth/bluetooth_remote_gatt_service_winrt.h
index 7585293..7d06abd 100644
--- a/device/bluetooth/bluetooth_remote_gatt_service_winrt.h
+++ b/device/bluetooth/bluetooth_remote_gatt_service_winrt.h
@@ -34,6 +34,12 @@
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                  GenericAttributeProfile::IGattDeviceService>
           gatt_service);
+
+  BluetoothRemoteGattServiceWinrt(const BluetoothRemoteGattServiceWinrt&) =
+      delete;
+  BluetoothRemoteGattServiceWinrt& operator=(
+      const BluetoothRemoteGattServiceWinrt&) = delete;
+
   ~BluetoothRemoteGattServiceWinrt() override;
 
   // BluetoothRemoteGattService:
@@ -134,8 +140,6 @@
   BluetoothUUID uuid_;
   uint16_t attribute_handle_;
   std::string identifier_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_rfcomm_channel_mac.h b/device/bluetooth/bluetooth_rfcomm_channel_mac.h
index dee90386..35451c7b 100644
--- a/device/bluetooth/bluetooth_rfcomm_channel_mac.h
+++ b/device/bluetooth/bluetooth_rfcomm_channel_mac.h
@@ -27,6 +27,11 @@
   // NOTE: The |channel| is expected to already be retained.
   BluetoothRfcommChannelMac(BluetoothSocketMac* socket,
                             IOBluetoothRFCOMMChannel* channel);
+
+  BluetoothRfcommChannelMac(const BluetoothRfcommChannelMac&) = delete;
+  BluetoothRfcommChannelMac& operator=(const BluetoothRfcommChannelMac&) =
+      delete;
+
   ~BluetoothRfcommChannelMac() override;
 
   // Opens a new RFCOMM channel with Channel ID |channel_id| to the target
@@ -61,8 +66,6 @@
 
   // The delegate for the native channel.
   base::scoped_nsobject<BluetoothRfcommChannelDelegate> delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRfcommChannelMac);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/bluetooth_task_manager_win.h b/device/bluetooth/bluetooth_task_manager_win.h
index 259ba8d..328b49d 100644
--- a/device/bluetooth/bluetooth_task_manager_win.h
+++ b/device/bluetooth/bluetooth_task_manager_win.h
@@ -55,6 +55,10 @@
 
   struct DEVICE_BLUETOOTH_EXPORT ServiceRecordState {
     ServiceRecordState();
+
+    ServiceRecordState(const ServiceRecordState&) = delete;
+    ServiceRecordState& operator=(const ServiceRecordState&) = delete;
+
     ~ServiceRecordState();
     // Properties common to Bluetooth Classic and LE devices.
     std::string name;
@@ -68,13 +72,14 @@
     // service must use service device path instead of resident device device
     // path.
     base::FilePath path;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(ServiceRecordState);
   };
 
   struct DEVICE_BLUETOOTH_EXPORT DeviceState {
     DeviceState();
+
+    DeviceState(const DeviceState&) = delete;
+    DeviceState& operator=(const DeviceState&) = delete;
+
     ~DeviceState();
 
     bool is_bluetooth_classic() const { return path.empty(); }
@@ -90,9 +95,6 @@
     uint32_t bluetooth_class;
     // Properties specific to Bluetooth LE devices.
     base::FilePath path;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(DeviceState);
   };
 
   class DEVICE_BLUETOOTH_EXPORT Observer {
diff --git a/device/bluetooth/bluez/bluetooth_adapter_profile_bluez.h b/device/bluetooth/bluez/bluetooth_adapter_profile_bluez.h
index 583ed4b..8b8804f5 100644
--- a/device/bluetooth/bluez/bluetooth_adapter_profile_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_adapter_profile_bluez.h
@@ -48,6 +48,10 @@
       ProfileRegisteredCallback success_callback,
       bluez::BluetoothProfileManagerClient::ErrorCallback error_callback);
 
+  BluetoothAdapterProfileBlueZ(const BluetoothAdapterProfileBlueZ&) = delete;
+  BluetoothAdapterProfileBlueZ& operator=(const BluetoothAdapterProfileBlueZ&) =
+      delete;
+
   ~BluetoothAdapterProfileBlueZ() override;
 
   // The object path of the profile.
@@ -106,8 +110,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAdapterProfileBlueZ> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterProfileBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
index 6a9486d..76330b3 100644
--- a/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
+++ b/device/bluetooth/bluez/bluetooth_bluez_unittest.cc
@@ -149,6 +149,10 @@
 class FakeBleScanParserImpl : public data_decoder::mojom::BleScanParser {
  public:
   FakeBleScanParserImpl() = default;
+
+  FakeBleScanParserImpl(const FakeBleScanParserImpl&) = delete;
+  FakeBleScanParserImpl& operator=(const FakeBleScanParserImpl&) = delete;
+
   ~FakeBleScanParserImpl() override = default;
 
   // mojom::BleScanParser:
@@ -156,8 +160,6 @@
              ParseCallback callback) override {
     std::move(callback).Run(nullptr);
   }
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBleScanParserImpl);
 };
 #endif
 
diff --git a/device/bluetooth/bluez/bluetooth_device_bluez.h b/device/bluetooth/bluez/bluetooth_device_bluez.h
index 48c54cb5..048951f 100644
--- a/device/bluetooth/bluez/bluetooth_device_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_device_bluez.h
@@ -50,6 +50,9 @@
   using GetServiceRecordsErrorCallback =
       base::OnceCallback<void(BluetoothServiceRecordBlueZ::ErrorCode)>;
 
+  BluetoothDeviceBlueZ(const BluetoothDeviceBlueZ&) = delete;
+  BluetoothDeviceBlueZ& operator=(const BluetoothDeviceBlueZ&) = delete;
+
   ~BluetoothDeviceBlueZ() override;
 
   // BluetoothDevice override
@@ -309,8 +312,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothDeviceBlueZ> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_gatt_connection_bluez.h b/device/bluetooth/bluez/bluetooth_gatt_connection_bluez.h
index 91504b2c..1a7a4c0f 100644
--- a/device/bluetooth/bluez/bluetooth_gatt_connection_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_gatt_connection_bluez.h
@@ -32,6 +32,11 @@
       scoped_refptr<device::BluetoothAdapter> adapter,
       const std::string& device_address,
       const dbus::ObjectPath& object_path);
+
+  BluetoothGattConnectionBlueZ(const BluetoothGattConnectionBlueZ&) = delete;
+  BluetoothGattConnectionBlueZ& operator=(const BluetoothGattConnectionBlueZ&) =
+      delete;
+
   ~BluetoothGattConnectionBlueZ() override;
 
   // BluetoothGattConnection overrides.
@@ -50,8 +55,6 @@
   // D-Bus object path of the underlying device. This is used to filter observer
   // events.
   dbus::ObjectPath object_path_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattConnectionBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_local_gatt_characteristic_bluez.h b/device/bluetooth/bluez/bluetooth_local_gatt_characteristic_bluez.h
index 5bf6c40..ed0fe069 100644
--- a/device/bluetooth/bluez/bluetooth_local_gatt_characteristic_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_local_gatt_characteristic_bluez.h
@@ -32,6 +32,12 @@
       Properties properties,
       Permissions permissions,
       BluetoothLocalGattServiceBlueZ* service);
+
+  BluetoothLocalGattCharacteristicBlueZ(
+      const BluetoothLocalGattCharacteristicBlueZ&) = delete;
+  BluetoothLocalGattCharacteristicBlueZ& operator=(
+      const BluetoothLocalGattCharacteristicBlueZ&) = delete;
+
   ~BluetoothLocalGattCharacteristicBlueZ() override;
 
   // device::BluetoothGattCharacteristic overrides:
@@ -76,8 +82,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothLocalGattCharacteristicBlueZ> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothLocalGattCharacteristicBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_local_gatt_descriptor_bluez.h b/device/bluetooth/bluez/bluetooth_local_gatt_descriptor_bluez.h
index 261ae25..7283da4 100644
--- a/device/bluetooth/bluez/bluetooth_local_gatt_descriptor_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_local_gatt_descriptor_bluez.h
@@ -27,6 +27,12 @@
       const device::BluetoothUUID& uuid,
       device::BluetoothGattCharacteristic::Permissions permissions,
       BluetoothLocalGattCharacteristicBlueZ* characteristic);
+
+  BluetoothLocalGattDescriptorBlueZ(const BluetoothLocalGattDescriptorBlueZ&) =
+      delete;
+  BluetoothLocalGattDescriptorBlueZ& operator=(
+      const BluetoothLocalGattDescriptorBlueZ&) = delete;
+
   ~BluetoothLocalGattDescriptorBlueZ() override;
 
   // device::BluetoothLocalGattDescriptor overrides.
@@ -52,8 +58,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothLocalGattDescriptorBlueZ> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothLocalGattDescriptorBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h b/device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h
index 7c30ba45..2fde43f5 100644
--- a/device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_local_gatt_service_bluez.h
@@ -33,6 +33,11 @@
       bool is_primary,
       device::BluetoothLocalGattService::Delegate* delegate);
 
+  BluetoothLocalGattServiceBlueZ(const BluetoothLocalGattServiceBlueZ&) =
+      delete;
+  BluetoothLocalGattServiceBlueZ& operator=(
+      const BluetoothLocalGattServiceBlueZ&) = delete;
+
   ~BluetoothLocalGattServiceBlueZ() override;
 
   // device::BluetoothGattService overrides.
@@ -89,8 +94,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothLocalGattServiceBlueZ> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothLocalGattServiceBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_pairing_bluez.h b/device/bluetooth/bluez/bluetooth_pairing_bluez.h
index 8b1d988f..8cfbd676 100644
--- a/device/bluetooth/bluez/bluetooth_pairing_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_pairing_bluez.h
@@ -24,6 +24,10 @@
   BluetoothPairingBlueZ(
       BluetoothDeviceBlueZ* device,
       device::BluetoothDevice::PairingDelegate* pairing_delegate);
+
+  BluetoothPairingBlueZ(const BluetoothPairingBlueZ&) = delete;
+  BluetoothPairingBlueZ& operator=(const BluetoothPairingBlueZ&) = delete;
+
   ~BluetoothPairingBlueZ();
 
   // Indicates whether the device is currently pairing and expecting a
@@ -142,8 +146,6 @@
       passkey_callback_;
   bluez::BluetoothAgentServiceProvider::Delegate::ConfirmationCallback
       confirmation_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothPairingBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_remote_gatt_characteristic_bluez.h b/device/bluetooth/bluez/bluetooth_remote_gatt_characteristic_bluez.h
index 7fc989f..c7ff670 100644
--- a/device/bluetooth/bluez/bluetooth_remote_gatt_characteristic_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_remote_gatt_characteristic_bluez.h
@@ -45,6 +45,11 @@
       public BluetoothGattDescriptorClient::Observer,
       public device::BluetoothRemoteGattCharacteristic {
  public:
+  BluetoothRemoteGattCharacteristicBlueZ(
+      const BluetoothRemoteGattCharacteristicBlueZ&) = delete;
+  BluetoothRemoteGattCharacteristicBlueZ& operator=(
+      const BluetoothRemoteGattCharacteristicBlueZ&) = delete;
+
   // device::BluetoothGattCharacteristic overrides.
   ~BluetoothRemoteGattCharacteristicBlueZ() override;
   device::BluetoothUUID GetUUID() const override;
@@ -146,8 +151,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothRemoteGattCharacteristicBlueZ>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_remote_gatt_descriptor_bluez.h b/device/bluetooth/bluez/bluetooth_remote_gatt_descriptor_bluez.h
index 743c008..027af754 100644
--- a/device/bluetooth/bluez/bluetooth_remote_gatt_descriptor_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_remote_gatt_descriptor_bluez.h
@@ -28,6 +28,11 @@
     : public BluetoothGattDescriptorBlueZ,
       public device::BluetoothRemoteGattDescriptor {
  public:
+  BluetoothRemoteGattDescriptorBlueZ(
+      const BluetoothRemoteGattDescriptorBlueZ&) = delete;
+  BluetoothRemoteGattDescriptorBlueZ& operator=(
+      const BluetoothRemoteGattDescriptorBlueZ&) = delete;
+
   // device::BluetoothRemoteGattDescriptor overrides.
   ~BluetoothRemoteGattDescriptorBlueZ() override;
   device::BluetoothUUID GetUUID() const override;
@@ -66,8 +71,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothRemoteGattDescriptorBlueZ> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h b/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h
index 3d288d8..c8c77f10 100644
--- a/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h
+++ b/device/bluetooth/bluez/bluetooth_remote_gatt_service_bluez.h
@@ -41,6 +41,11 @@
       public BluetoothGattCharacteristicClient::Observer,
       public device::BluetoothRemoteGattService {
  public:
+  BluetoothRemoteGattServiceBlueZ(const BluetoothRemoteGattServiceBlueZ&) =
+      delete;
+  BluetoothRemoteGattServiceBlueZ& operator=(
+      const BluetoothRemoteGattServiceBlueZ&) = delete;
+
   ~BluetoothRemoteGattServiceBlueZ() override;
 
   // device::BluetoothRemoteGattService overrides.
@@ -99,8 +104,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothRemoteGattServiceBlueZ> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceBlueZ);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/cast/bluetooth_adapter_cast_unittest.cc b/device/bluetooth/cast/bluetooth_adapter_cast_unittest.cc
index 03e4360..f1b61eef 100644
--- a/device/bluetooth/cast/bluetooth_adapter_cast_unittest.cc
+++ b/device/bluetooth/cast/bluetooth_adapter_cast_unittest.cc
@@ -15,14 +15,16 @@
 class BluetoothAdapterCastTest : public testing::Test {
  public:
   BluetoothAdapterCastTest() = default;
+
+  BluetoothAdapterCastTest(const BluetoothAdapterCastTest&) = delete;
+  BluetoothAdapterCastTest& operator=(const BluetoothAdapterCastTest&) = delete;
+
   ~BluetoothAdapterCastTest() override {
     BluetoothAdapterCast::ResetFactoryForTest();
   }
 
  private:
   base::test::TaskEnvironment task_environment_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterCastTest);
 };
 
 TEST_F(BluetoothAdapterCastTest, TestSetFactory) {
diff --git a/device/bluetooth/cast/bluetooth_device_cast.h b/device/bluetooth/cast/bluetooth_device_cast.h
index 73cdee7..76a1d0b 100644
--- a/device/bluetooth/cast/bluetooth_device_cast.h
+++ b/device/bluetooth/cast/bluetooth_device_cast.h
@@ -33,6 +33,10 @@
   BluetoothDeviceCast(
       BluetoothAdapter* adapter,
       scoped_refptr<chromecast::bluetooth::RemoteDevice> device);
+
+  BluetoothDeviceCast(const BluetoothDeviceCast&) = delete;
+  BluetoothDeviceCast& operator=(const BluetoothDeviceCast&) = delete;
+
   ~BluetoothDeviceCast() override;
 
   // BluetoothDevice implementation:
@@ -133,8 +137,6 @@
   absl::optional<std::string> name_;
 
   base::WeakPtrFactory<BluetoothDeviceCast> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceCast);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.h b/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.h
index dd297da..e65eaa41 100644
--- a/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.h
+++ b/device/bluetooth/cast/bluetooth_remote_gatt_characteristic_cast.h
@@ -34,6 +34,12 @@
       BluetoothRemoteGattServiceCast* service,
       scoped_refptr<chromecast::bluetooth::RemoteCharacteristic>
           characteristic);
+
+  BluetoothRemoteGattCharacteristicCast(
+      const BluetoothRemoteGattCharacteristicCast&) = delete;
+  BluetoothRemoteGattCharacteristicCast& operator=(
+      const BluetoothRemoteGattCharacteristicCast&) = delete;
+
   ~BluetoothRemoteGattCharacteristicCast() override;
 
   // BluetoothGattCharacteristic implementation:
@@ -94,8 +100,6 @@
   std::vector<uint8_t> value_;
 
   base::WeakPtrFactory<BluetoothRemoteGattCharacteristicCast> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattCharacteristicCast);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/cast/bluetooth_remote_gatt_descriptor_cast.h b/device/bluetooth/cast/bluetooth_remote_gatt_descriptor_cast.h
index f799cb0..8b2d37f 100644
--- a/device/bluetooth/cast/bluetooth_remote_gatt_descriptor_cast.h
+++ b/device/bluetooth/cast/bluetooth_remote_gatt_descriptor_cast.h
@@ -30,6 +30,12 @@
   BluetoothRemoteGattDescriptorCast(
       BluetoothRemoteGattCharacteristicCast* characteristic,
       scoped_refptr<chromecast::bluetooth::RemoteDescriptor> remote_descriptor);
+
+  BluetoothRemoteGattDescriptorCast(const BluetoothRemoteGattDescriptorCast&) =
+      delete;
+  BluetoothRemoteGattDescriptorCast& operator=(
+      const BluetoothRemoteGattDescriptorCast&) = delete;
+
   ~BluetoothRemoteGattDescriptorCast() override;
 
   // BluetoothGattDescriptor implementation:
@@ -69,7 +75,6 @@
   std::vector<uint8_t> value_;
 
   base::WeakPtrFactory<BluetoothRemoteGattDescriptorCast> weak_factory_;
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattDescriptorCast);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/cast/bluetooth_remote_gatt_service_cast.h b/device/bluetooth/cast/bluetooth_remote_gatt_service_cast.h
index 8280cac..0741aeee 100644
--- a/device/bluetooth/cast/bluetooth_remote_gatt_service_cast.h
+++ b/device/bluetooth/cast/bluetooth_remote_gatt_service_cast.h
@@ -29,6 +29,12 @@
   BluetoothRemoteGattServiceCast(
       BluetoothDeviceCast* device,
       scoped_refptr<chromecast::bluetooth::RemoteService> remote_service);
+
+  BluetoothRemoteGattServiceCast(const BluetoothRemoteGattServiceCast&) =
+      delete;
+  BluetoothRemoteGattServiceCast& operator=(
+      const BluetoothRemoteGattServiceCast&) = delete;
+
   ~BluetoothRemoteGattServiceCast() override;
 
   // BluetoothGattService implementation:
@@ -43,8 +49,6 @@
  private:
   BluetoothDeviceCast* const device_;
   scoped_refptr<chromecast::bluetooth::RemoteService> remote_service_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceCast);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.cc b/device/bluetooth/dbus/bluetooth_adapter_client.cc
index 16e1ea6d..ae31740 100644
--- a/device/bluetooth/dbus/bluetooth_adapter_client.cc
+++ b/device/bluetooth/dbus/bluetooth_adapter_client.cc
@@ -196,6 +196,10 @@
  public:
   BluetoothAdapterClientImpl() = default;
 
+  BluetoothAdapterClientImpl(const BluetoothAdapterClientImpl&) = delete;
+  BluetoothAdapterClientImpl& operator=(const BluetoothAdapterClientImpl&) =
+      delete;
+
   ~BluetoothAdapterClientImpl() override {
     // There is an instance of this client that is created but not initialized
     // on Linux. See 'Alternate D-Bus Client' note in bluez_dbus_manager.h.
@@ -607,8 +611,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAdapterClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClientImpl);
 };
 
 BluetoothAdapterClient::BluetoothAdapterClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_adapter_client.h b/device/bluetooth/dbus/bluetooth_adapter_client.h
index 9046680..ce2f55ae 100644
--- a/device/bluetooth/dbus/bluetooth_adapter_client.h
+++ b/device/bluetooth/dbus/bluetooth_adapter_client.h
@@ -39,6 +39,10 @@
   // method.
   struct DiscoveryFilter {
     DiscoveryFilter();
+
+    DiscoveryFilter(const DiscoveryFilter&) = delete;
+    DiscoveryFilter& operator=(const DiscoveryFilter&) = delete;
+
     ~DiscoveryFilter();
 
     // Copy content of |filter| into this filter
@@ -48,9 +52,6 @@
     std::unique_ptr<int16_t> rssi;
     std::unique_ptr<uint16_t> pathloss;
     std::unique_ptr<std::string> transport;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(DiscoveryFilter);
   };
 
   // Represent an error sent through DBus.
@@ -136,6 +137,9 @@
                                         const std::string& property_name) {}
   };
 
+  BluetoothAdapterClient(const BluetoothAdapterClient&) = delete;
+  BluetoothAdapterClient& operator=(const BluetoothAdapterClient&) = delete;
+
   ~BluetoothAdapterClient() override;
 
   // Adds and removes observers for events on all local bluetooth
@@ -238,9 +242,6 @@
 
  protected:
   BluetoothAdapterClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdapterClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_agent_manager_client.cc b/device/bluetooth/dbus/bluetooth_agent_manager_client.cc
index b760e86..37458e8 100644
--- a/device/bluetooth/dbus/bluetooth_agent_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_agent_manager_client.cc
@@ -26,6 +26,11 @@
  public:
   BluetoothAgentManagerClientImpl() {}
 
+  BluetoothAgentManagerClientImpl(const BluetoothAgentManagerClientImpl&) =
+      delete;
+  BluetoothAgentManagerClientImpl& operator=(
+      const BluetoothAgentManagerClientImpl&) = delete;
+
   ~BluetoothAgentManagerClientImpl() override = default;
 
   // BluetoothAgentManagerClient override.
@@ -180,8 +185,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAgentManagerClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAgentManagerClientImpl);
 };
 
 BluetoothAgentManagerClient::BluetoothAgentManagerClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_agent_manager_client.h b/device/bluetooth/dbus/bluetooth_agent_manager_client.h
index 3684c24..02ca5a17 100644
--- a/device/bluetooth/dbus/bluetooth_agent_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_agent_manager_client.h
@@ -36,6 +36,10 @@
     virtual void AgentManagerRemoved(const dbus::ObjectPath& object_path) {}
   };
 
+  BluetoothAgentManagerClient(const BluetoothAgentManagerClient&) = delete;
+  BluetoothAgentManagerClient& operator=(const BluetoothAgentManagerClient&) =
+      delete;
+
   ~BluetoothAgentManagerClient() override;
 
   // Adds and removes observers for events on agent manager.
@@ -79,9 +83,6 @@
 
  protected:
   BluetoothAgentManagerClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAgentManagerClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_agent_service_provider.cc b/device/bluetooth/dbus/bluetooth_agent_service_provider.cc
index 2ab3ba62..51e90b3 100644
--- a/device/bluetooth/dbus/bluetooth_agent_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_agent_service_provider.cc
@@ -109,6 +109,11 @@
                        weak_ptr_factory_.GetWeakPtr()));
   }
 
+  BluetoothAgentServiceProviderImpl(const BluetoothAgentServiceProviderImpl&) =
+      delete;
+  BluetoothAgentServiceProviderImpl& operator=(
+      const BluetoothAgentServiceProviderImpl&) = delete;
+
   ~BluetoothAgentServiceProviderImpl() override {
     DVLOG(1) << "Cleaning up Bluetooth Agent: " << object_path_.value();
 
@@ -441,8 +446,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAgentServiceProviderImpl> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAgentServiceProviderImpl);
 };
 
 BluetoothAgentServiceProvider::BluetoothAgentServiceProvider() = default;
diff --git a/device/bluetooth/dbus/bluetooth_agent_service_provider.h b/device/bluetooth/dbus/bluetooth_agent_service_provider.h
index 5238b14..707eac8b 100644
--- a/device/bluetooth/dbus/bluetooth_agent_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_agent_service_provider.h
@@ -157,6 +157,10 @@
     virtual void Cancel() = 0;
   };
 
+  BluetoothAgentServiceProvider(const BluetoothAgentServiceProvider&) = delete;
+  BluetoothAgentServiceProvider& operator=(
+      const BluetoothAgentServiceProvider&) = delete;
+
   virtual ~BluetoothAgentServiceProvider();
 
   // Creates the instance where |bus| is the D-Bus bus connection to export
@@ -170,9 +174,6 @@
 
  protected:
   BluetoothAgentServiceProvider();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAgentServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_battery_client.cc b/device/bluetooth/dbus/bluetooth_battery_client.cc
index a84868c..e120af2 100644
--- a/device/bluetooth/dbus/bluetooth_battery_client.cc
+++ b/device/bluetooth/dbus/bluetooth_battery_client.cc
@@ -33,6 +33,10 @@
  public:
   BluetoothBatteryClientImpl() = default;
 
+  BluetoothBatteryClientImpl(const BluetoothBatteryClientImpl&) = delete;
+  BluetoothBatteryClientImpl& operator=(const BluetoothBatteryClientImpl&) =
+      delete;
+
   ~BluetoothBatteryClientImpl() override {
     // There is an instance of this client that is created but not initialized
     // on Linux. See 'Alternate D-Bus Client' note in bluez_dbus_manager.h.
@@ -118,8 +122,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothBatteryClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothBatteryClientImpl);
 };
 
 BluetoothBatteryClient::BluetoothBatteryClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_battery_client.h b/device/bluetooth/dbus/bluetooth_battery_client.h
index 472ceac8..e9bb795 100644
--- a/device/bluetooth/dbus/bluetooth_battery_client.h
+++ b/device/bluetooth/dbus/bluetooth_battery_client.h
@@ -53,6 +53,9 @@
                                         const std::string& property_name) {}
   };
 
+  BluetoothBatteryClient(const BluetoothBatteryClient&) = delete;
+  BluetoothBatteryClient& operator=(const BluetoothBatteryClient&) = delete;
+
   ~BluetoothBatteryClient() override;
 
   // Adds and removes observers for events on all remote bluetooth
@@ -70,9 +73,6 @@
 
  protected:
   BluetoothBatteryClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothBatteryClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h
index cab86dd..440f8b3 100644
--- a/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h
+++ b/device/bluetooth/dbus/bluetooth_dbus_client_bundle.h
@@ -34,6 +34,11 @@
 class DEVICE_BLUETOOTH_EXPORT BluetoothDBusClientBundle {
  public:
   explicit BluetoothDBusClientBundle(bool use_fakes);
+
+  BluetoothDBusClientBundle(const BluetoothDBusClientBundle&) = delete;
+  BluetoothDBusClientBundle& operator=(const BluetoothDBusClientBundle&) =
+      delete;
+
   ~BluetoothDBusClientBundle();
 
   // Returns true if |client| is stubbed.
@@ -133,8 +138,6 @@
   // See "Alternate D-Bus Client" note in bluez_dbus_manager.h.
   std::unique_ptr<BluetoothAdapterClient> alternate_bluetooth_adapter_client_;
   std::unique_ptr<BluetoothDeviceClient> alternate_bluetooth_device_client_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDBusClientBundle);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_debug_manager_client.cc b/device/bluetooth/dbus/bluetooth_debug_manager_client.cc
index f879615..337b36c 100644
--- a/device/bluetooth/dbus/bluetooth_debug_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_debug_manager_client.cc
@@ -36,6 +36,11 @@
  public:
   BluetoothDebugManagerClientImpl() = default;
 
+  BluetoothDebugManagerClientImpl(const BluetoothDebugManagerClientImpl&) =
+      delete;
+  BluetoothDebugManagerClientImpl& operator=(
+      const BluetoothDebugManagerClientImpl&) = delete;
+
   ~BluetoothDebugManagerClientImpl() override = default;
 
   // BluetoothDebugManagerClient override.
@@ -122,8 +127,6 @@
   dbus::ObjectManager* object_manager_;
 
   base::WeakPtrFactory<BluetoothDebugManagerClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDebugManagerClientImpl);
 };
 
 BluetoothDebugManagerClient::BluetoothDebugManagerClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_debug_manager_client.h b/device/bluetooth/dbus/bluetooth_debug_manager_client.h
index c830287..3b6b46ed 100644
--- a/device/bluetooth/dbus/bluetooth_debug_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_debug_manager_client.h
@@ -21,6 +21,10 @@
 class DEVICE_BLUETOOTH_EXPORT BluetoothDebugManagerClient
     : public BluezDBusClient {
  public:
+  BluetoothDebugManagerClient(const BluetoothDebugManagerClient&) = delete;
+  BluetoothDebugManagerClient& operator=(const BluetoothDebugManagerClient&) =
+      delete;
+
   ~BluetoothDebugManagerClient() override;
 
   // The ErrorCallback is used by debug manager methods to indicate failure.
@@ -47,9 +51,6 @@
 
  protected:
   BluetoothDebugManagerClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDebugManagerClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_device_client.cc b/device/bluetooth/dbus/bluetooth_device_client.cc
index c7d6980..d8251e6 100644
--- a/device/bluetooth/dbus/bluetooth_device_client.cc
+++ b/device/bluetooth/dbus/bluetooth_device_client.cc
@@ -225,6 +225,10 @@
  public:
   BluetoothDeviceClientImpl() : object_manager_(nullptr) {}
 
+  BluetoothDeviceClientImpl(const BluetoothDeviceClientImpl&) = delete;
+  BluetoothDeviceClientImpl& operator=(const BluetoothDeviceClientImpl&) =
+      delete;
+
   ~BluetoothDeviceClientImpl() override {
     // There is an instance of this client that is created but not initialized
     // on Linux. See 'Alternate D-Bus Client' note in bluez_dbus_manager.h.
@@ -746,8 +750,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothDeviceClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClientImpl);
 };
 
 BluetoothDeviceClient::BluetoothDeviceClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_device_client.h b/device/bluetooth/dbus/bluetooth_device_client.h
index a7a28e6..17ac8415 100644
--- a/device/bluetooth/dbus/bluetooth_device_client.h
+++ b/device/bluetooth/dbus/bluetooth_device_client.h
@@ -176,6 +176,9 @@
                                        const std::string& property_name) {}
   };
 
+  BluetoothDeviceClient(const BluetoothDeviceClient&) = delete;
+  BluetoothDeviceClient& operator=(const BluetoothDeviceClient&) = delete;
+
   ~BluetoothDeviceClient() override;
 
   // Adds and removes observers for events on all remote bluetooth
@@ -296,9 +299,6 @@
 
  protected:
   BluetoothDeviceClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothDeviceClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h
index adfff73..d25fee3 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider.h
@@ -26,6 +26,11 @@
 // hierarchies.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattApplicationServiceProvider {
  public:
+  BluetoothGattApplicationServiceProvider(
+      const BluetoothGattApplicationServiceProvider&) = delete;
+  BluetoothGattApplicationServiceProvider& operator=(
+      const BluetoothGattApplicationServiceProvider&) = delete;
+
   virtual ~BluetoothGattApplicationServiceProvider();
 
   // Creates individual service providers for all the attributes managed by the
@@ -63,9 +68,6 @@
   // List of GATT Descriptor service providers managed by this object manager.
   std::vector<std::unique_ptr<BluetoothGattDescriptorServiceProvider>>
       descriptor_providers_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattApplicationServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h
index 701dd22..63d398c94 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_application_service_provider_impl.h
@@ -39,6 +39,12 @@
       const dbus::ObjectPath& object_path,
       const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
           services);
+
+  BluetoothGattApplicationServiceProviderImpl(
+      const BluetoothGattApplicationServiceProviderImpl&) = delete;
+  BluetoothGattApplicationServiceProviderImpl& operator=(
+      const BluetoothGattApplicationServiceProviderImpl&) = delete;
+
   ~BluetoothGattApplicationServiceProviderImpl() override;
 
  private:
@@ -98,8 +104,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattApplicationServiceProviderImpl>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattApplicationServiceProviderImpl);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h b/device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h
index 13c0efc7e..14f3cb1 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_attribute_value_delegate.h
@@ -30,6 +30,12 @@
  public:
   explicit BluetoothGattAttributeValueDelegate(
       BluetoothLocalGattServiceBlueZ* service);
+
+  BluetoothGattAttributeValueDelegate(
+      const BluetoothGattAttributeValueDelegate&) = delete;
+  BluetoothGattAttributeValueDelegate& operator=(
+      const BluetoothGattAttributeValueDelegate&) = delete;
+
   virtual ~BluetoothGattAttributeValueDelegate();
 
   // This method will be called when a remote device requests to read the
@@ -93,8 +99,6 @@
 
  private:
   const BluetoothLocalGattServiceBlueZ* service_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattAttributeValueDelegate);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
index 23e2521..c9b5adf 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.cc
@@ -50,6 +50,11 @@
  public:
   BluetoothGattCharacteristicClientImpl() : object_manager_(nullptr) {}
 
+  BluetoothGattCharacteristicClientImpl(
+      const BluetoothGattCharacteristicClientImpl&) = delete;
+  BluetoothGattCharacteristicClientImpl& operator=(
+      const BluetoothGattCharacteristicClientImpl&) = delete;
+
   ~BluetoothGattCharacteristicClientImpl() override {
     object_manager_->UnregisterInterface(
         bluetooth_gatt_characteristic::kBluetoothGattCharacteristicInterface);
@@ -343,8 +348,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattCharacteristicClientImpl> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClientImpl);
 };
 
 BluetoothGattCharacteristicClient::BluetoothGattCharacteristicClient() =
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h
index cbebcdc..24ffaf0 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_client.h
@@ -85,6 +85,11 @@
       absl::optional<device::BluetoothGattService::GattErrorCode> error_code,
       const std::vector<uint8_t>& value)>;
 
+  BluetoothGattCharacteristicClient(const BluetoothGattCharacteristicClient&) =
+      delete;
+  BluetoothGattCharacteristicClient& operator=(
+      const BluetoothGattCharacteristicClient&) = delete;
+
   ~BluetoothGattCharacteristicClient() override;
 
   // Adds and removes observers for events on all remote GATT characteristics.
@@ -156,9 +161,6 @@
 
  protected:
   BluetoothGattCharacteristicClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
index 041467e..139afca 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider.h
@@ -34,6 +34,11 @@
 // "Value" property.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattCharacteristicServiceProvider {
  public:
+  BluetoothGattCharacteristicServiceProvider(
+      const BluetoothGattCharacteristicServiceProvider&) = delete;
+  BluetoothGattCharacteristicServiceProvider& operator=(
+      const BluetoothGattCharacteristicServiceProvider&) = delete;
+
   virtual ~BluetoothGattCharacteristicServiceProvider();
 
   // Send a PropertyChanged signal to notify the Bluetooth daemon that the value
@@ -71,9 +76,6 @@
 
  protected:
   BluetoothGattCharacteristicServiceProvider();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h
index 7bd8b416..a0a7bd62 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_characteristic_service_provider_impl.h
@@ -38,6 +38,11 @@
       const std::vector<std::string>& flags,
       const dbus::ObjectPath& service_path);
 
+  BluetoothGattCharacteristicServiceProviderImpl(
+      const BluetoothGattCharacteristicServiceProviderImpl&) = delete;
+  BluetoothGattCharacteristicServiceProviderImpl& operator=(
+      const BluetoothGattCharacteristicServiceProviderImpl&) = delete;
+
   ~BluetoothGattCharacteristicServiceProviderImpl() override;
 
   // BluetoothGattCharacteristicServiceProvider override.
@@ -163,8 +168,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattCharacteristicServiceProviderImpl>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattCharacteristicServiceProviderImpl);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
index 1ced400c..f09b74c 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.cc
@@ -53,6 +53,11 @@
  public:
   BluetoothGattDescriptorClientImpl() : object_manager_(nullptr) {}
 
+  BluetoothGattDescriptorClientImpl(const BluetoothGattDescriptorClientImpl&) =
+      delete;
+  BluetoothGattDescriptorClientImpl& operator=(
+      const BluetoothGattDescriptorClientImpl&) = delete;
+
   ~BluetoothGattDescriptorClientImpl() override {
     object_manager_->UnregisterInterface(
         bluetooth_gatt_descriptor::kBluetoothGattDescriptorInterface);
@@ -252,8 +257,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattDescriptorClientImpl> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorClientImpl);
 };
 
 BluetoothGattDescriptorClient::BluetoothGattDescriptorClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h
index 45c94b1..ca7b7e4c 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_client.h
@@ -74,6 +74,10 @@
       absl::optional<device::BluetoothGattService::GattErrorCode> error_code,
       const std::vector<uint8_t>& value)>;
 
+  BluetoothGattDescriptorClient(const BluetoothGattDescriptorClient&) = delete;
+  BluetoothGattDescriptorClient& operator=(
+      const BluetoothGattDescriptorClient&) = delete;
+
   ~BluetoothGattDescriptorClient() override;
 
   // Adds and removes observers for events on all remote GATT descriptors. Check
@@ -113,9 +117,6 @@
 
  protected:
   BluetoothGattDescriptorClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
index 98bc7f1c..12f42d9 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider.h
@@ -34,6 +34,11 @@
 // "Value" property.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattDescriptorServiceProvider {
  public:
+  BluetoothGattDescriptorServiceProvider(
+      const BluetoothGattDescriptorServiceProvider&) = delete;
+  BluetoothGattDescriptorServiceProvider& operator=(
+      const BluetoothGattDescriptorServiceProvider&) = delete;
+
   virtual ~BluetoothGattDescriptorServiceProvider();
 
   // Send a PropertyChanged signal to notify the Bluetooth daemon that the value
@@ -70,9 +75,6 @@
 
  protected:
   BluetoothGattDescriptorServiceProvider();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h
index eb449d3..f1d0caed 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_descriptor_service_provider_impl.h
@@ -34,6 +34,12 @@
       const std::string& uuid,
       const std::vector<std::string>& flags,
       const dbus::ObjectPath& characteristic_path);
+
+  BluetoothGattDescriptorServiceProviderImpl(
+      const BluetoothGattDescriptorServiceProviderImpl&) = delete;
+  BluetoothGattDescriptorServiceProviderImpl& operator=(
+      const BluetoothGattDescriptorServiceProviderImpl&) = delete;
+
   ~BluetoothGattDescriptorServiceProviderImpl() override;
 
   // BluetoothGattDescriptorServiceProvider override.
@@ -131,8 +137,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattDescriptorServiceProviderImpl>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattDescriptorServiceProviderImpl);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
index 02fc937..9b4531c4 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.cc
@@ -33,6 +33,11 @@
  public:
   BluetoothGattManagerClientImpl() : object_manager_(nullptr) {}
 
+  BluetoothGattManagerClientImpl(const BluetoothGattManagerClientImpl&) =
+      delete;
+  BluetoothGattManagerClientImpl& operator=(
+      const BluetoothGattManagerClientImpl&) = delete;
+
   ~BluetoothGattManagerClientImpl() override = default;
 
   // BluetoothGattManagerClient override.
@@ -153,8 +158,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattManagerClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattManagerClientImpl);
 };
 
 BluetoothGattManagerClient::BluetoothGattManagerClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
index 102ac6a..c54bfd8 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_manager_client.h
@@ -26,6 +26,10 @@
     // later as we know more about how this will be used.
   };
 
+  BluetoothGattManagerClient(const BluetoothGattManagerClient&) = delete;
+  BluetoothGattManagerClient& operator=(const BluetoothGattManagerClient&) =
+      delete;
+
   ~BluetoothGattManagerClient() override;
 
   // The ErrorCallback is used by GATT manager methods to indicate failure. It
@@ -69,9 +73,6 @@
 
  protected:
   BluetoothGattManagerClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattManagerClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_client.cc b/device/bluetooth/dbus/bluetooth_gatt_service_client.cc
index 2ea601b..af1de99 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_client.cc
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_client.cc
@@ -34,6 +34,11 @@
  public:
   BluetoothGattServiceClientImpl() : object_manager_(nullptr) {}
 
+  BluetoothGattServiceClientImpl(const BluetoothGattServiceClientImpl&) =
+      delete;
+  BluetoothGattServiceClientImpl& operator=(
+      const BluetoothGattServiceClientImpl&) = delete;
+
   ~BluetoothGattServiceClientImpl() override {
     object_manager_->UnregisterInterface(
         bluetooth_gatt_service::kBluetoothGattServiceInterface);
@@ -127,8 +132,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattServiceClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceClientImpl);
 };
 
 BluetoothGattServiceClient::BluetoothGattServiceClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_client.h b/device/bluetooth/dbus/bluetooth_gatt_service_client.h
index f0dd1624..6f9d3e0 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_client.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_client.h
@@ -61,6 +61,10 @@
                                             const std::string& property_name) {}
   };
 
+  BluetoothGattServiceClient(const BluetoothGattServiceClient&) = delete;
+  BluetoothGattServiceClient& operator=(const BluetoothGattServiceClient&) =
+      delete;
+
   ~BluetoothGattServiceClient() override;
 
   // Adds and removes observers for events on all remote GATT services. Check
@@ -81,9 +85,6 @@
 
  protected:
   BluetoothGattServiceClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
index cc112c8..203999c0 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider.h
@@ -28,6 +28,11 @@
 // providers before registering a GATT service with the Bluetooth daemon.
 class DEVICE_BLUETOOTH_EXPORT BluetoothGattServiceServiceProvider {
  public:
+  BluetoothGattServiceServiceProvider(
+      const BluetoothGattServiceServiceProvider&) = delete;
+  BluetoothGattServiceServiceProvider& operator=(
+      const BluetoothGattServiceServiceProvider&) = delete;
+
   virtual ~BluetoothGattServiceServiceProvider();
 
   // Writes an array of the service's properties into the provided writer.
@@ -50,9 +55,6 @@
 
  protected:
   BluetoothGattServiceServiceProvider();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h
index eb68394..e9be0fc 100644
--- a/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h
+++ b/device/bluetooth/dbus/bluetooth_gatt_service_service_provider_impl.h
@@ -33,6 +33,11 @@
       bool is_primary,
       const std::vector<dbus::ObjectPath>& includes);
 
+  BluetoothGattServiceServiceProviderImpl(
+      const BluetoothGattServiceServiceProviderImpl&) = delete;
+  BluetoothGattServiceServiceProviderImpl& operator=(
+      const BluetoothGattServiceServiceProviderImpl&) = delete;
+
   ~BluetoothGattServiceServiceProviderImpl() override;
 
  private:
@@ -93,8 +98,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothGattServiceServiceProviderImpl>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothGattServiceServiceProviderImpl);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_input_client.cc b/device/bluetooth/dbus/bluetooth_input_client.cc
index af417df6..428e35e 100644
--- a/device/bluetooth/dbus/bluetooth_input_client.cc
+++ b/device/bluetooth/dbus/bluetooth_input_client.cc
@@ -34,6 +34,9 @@
  public:
   BluetoothInputClientImpl() : object_manager_(nullptr) {}
 
+  BluetoothInputClientImpl(const BluetoothInputClientImpl&) = delete;
+  BluetoothInputClientImpl& operator=(const BluetoothInputClientImpl&) = delete;
+
   ~BluetoothInputClientImpl() override {
     object_manager_->UnregisterInterface(
         bluetooth_input::kBluetoothInputInterface);
@@ -115,8 +118,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothInputClientImpl> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothInputClientImpl);
 };
 
 BluetoothInputClient::BluetoothInputClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_input_client.h b/device/bluetooth/dbus/bluetooth_input_client.h
index 91ca166..eac5c10 100644
--- a/device/bluetooth/dbus/bluetooth_input_client.h
+++ b/device/bluetooth/dbus/bluetooth_input_client.h
@@ -54,6 +54,9 @@
                                       const std::string& property_name) {}
   };
 
+  BluetoothInputClient(const BluetoothInputClient&) = delete;
+  BluetoothInputClient& operator=(const BluetoothInputClient&) = delete;
+
   ~BluetoothInputClient() override;
 
   // Adds and removes observers for events on all remote bluetooth input
@@ -71,9 +74,6 @@
 
  protected:
   BluetoothInputClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothInputClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
index 0123cce3..0aa4eea 100644
--- a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.cc
@@ -81,6 +81,11 @@
                        weak_ptr_factory_.GetWeakPtr()));
   }
 
+  BluetoothAdvertisementServiceProviderImpl(
+      const BluetoothAdvertisementServiceProviderImpl&) = delete;
+  BluetoothAdvertisementServiceProviderImpl& operator=(
+      const BluetoothAdvertisementServiceProviderImpl&) = delete;
+
   ~BluetoothAdvertisementServiceProviderImpl() override {
     DVLOG(1) << "Cleaning up Bluetooth Advertisement: " << object_path_.value();
 
@@ -443,8 +448,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAdvertisementServiceProviderImpl>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementServiceProviderImpl);
 };
 
 BluetoothLEAdvertisementServiceProvider::
diff --git a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h
index 5c32339..4798d2f 100644
--- a/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_le_advertisement_service_provider.h
@@ -48,6 +48,11 @@
     virtual void Released() = 0;
   };
 
+  BluetoothLEAdvertisementServiceProvider(
+      const BluetoothLEAdvertisementServiceProvider&) = delete;
+  BluetoothLEAdvertisementServiceProvider& operator=(
+      const BluetoothLEAdvertisementServiceProvider&) = delete;
+
   virtual ~BluetoothLEAdvertisementServiceProvider();
 
   const dbus::ObjectPath& object_path() { return object_path_; }
@@ -73,9 +78,6 @@
   // D-Bus object path of object we are exporting, kept so we can unregister
   // again in our destructor.
   dbus::ObjectPath object_path_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothLEAdvertisementServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
index 13eebd21..d917268 100644
--- a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.cc
@@ -26,6 +26,11 @@
  public:
   BluetoothAdvertisementManagerClientImpl() : object_manager_(nullptr) {}
 
+  BluetoothAdvertisementManagerClientImpl(
+      const BluetoothAdvertisementManagerClientImpl&) = delete;
+  BluetoothAdvertisementManagerClientImpl& operator=(
+      const BluetoothAdvertisementManagerClientImpl&) = delete;
+
   ~BluetoothAdvertisementManagerClientImpl() override {
     if (object_manager_) {
       object_manager_->UnregisterInterface(
@@ -211,8 +216,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothAdvertisementManagerClientImpl>
       weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothAdvertisementManagerClientImpl);
 };
 
 BluetoothLEAdvertisingManagerClient::BluetoothLEAdvertisingManagerClient() =
diff --git a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h
index e9cad0b..3302817 100644
--- a/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_le_advertising_manager_client.h
@@ -38,6 +38,11 @@
         const dbus::ObjectPath& object_path) {}
   };
 
+  BluetoothLEAdvertisingManagerClient(
+      const BluetoothLEAdvertisingManagerClient&) = delete;
+  BluetoothLEAdvertisingManagerClient& operator=(
+      const BluetoothLEAdvertisingManagerClient&) = delete;
+
   ~BluetoothLEAdvertisingManagerClient() override;
 
   // Adds and removes observers for events which change the advertising
@@ -89,9 +94,6 @@
 
  protected:
   BluetoothLEAdvertisingManagerClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothLEAdvertisingManagerClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_profile_manager_client.cc b/device/bluetooth/dbus/bluetooth_profile_manager_client.cc
index 5944ce8..0045e8b 100644
--- a/device/bluetooth/dbus/bluetooth_profile_manager_client.cc
+++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.cc
@@ -28,6 +28,11 @@
  public:
   BluetoothProfileManagerClientImpl() {}
 
+  BluetoothProfileManagerClientImpl(const BluetoothProfileManagerClientImpl&) =
+      delete;
+  BluetoothProfileManagerClientImpl& operator=(
+      const BluetoothProfileManagerClientImpl&) = delete;
+
   ~BluetoothProfileManagerClientImpl() override = default;
 
   // BluetoothProfileManagerClient override.
@@ -251,8 +256,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothProfileManagerClientImpl> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothProfileManagerClientImpl);
 };
 
 BluetoothProfileManagerClient::BluetoothProfileManagerClient() = default;
diff --git a/device/bluetooth/dbus/bluetooth_profile_manager_client.h b/device/bluetooth/dbus/bluetooth_profile_manager_client.h
index 79e3101..5f47863a 100644
--- a/device/bluetooth/dbus/bluetooth_profile_manager_client.h
+++ b/device/bluetooth/dbus/bluetooth_profile_manager_client.h
@@ -68,6 +68,10 @@
     std::unique_ptr<uint16_t> features;
   };
 
+  BluetoothProfileManagerClient(const BluetoothProfileManagerClient&) = delete;
+  BluetoothProfileManagerClient& operator=(
+      const BluetoothProfileManagerClient&) = delete;
+
   ~BluetoothProfileManagerClient() override;
 
   // The ErrorCallback is used by adapter methods to indicate failure.
@@ -101,9 +105,6 @@
 
  protected:
   BluetoothProfileManagerClient();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothProfileManagerClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluetooth_profile_service_provider.cc b/device/bluetooth/dbus/bluetooth_profile_service_provider.cc
index 2a0a460..54eee603 100644
--- a/device/bluetooth/dbus/bluetooth_profile_service_provider.cc
+++ b/device/bluetooth/dbus/bluetooth_profile_service_provider.cc
@@ -69,6 +69,11 @@
                        weak_ptr_factory_.GetWeakPtr()));
   }
 
+  BluetoothProfileServiceProviderImpl(
+      const BluetoothProfileServiceProviderImpl&) = delete;
+  BluetoothProfileServiceProviderImpl& operator=(
+      const BluetoothProfileServiceProviderImpl&) = delete;
+
   ~BluetoothProfileServiceProviderImpl() override {
     DVLOG(1) << "Cleaning up Bluetooth Profile: " << object_path_.value();
 
@@ -235,8 +240,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<BluetoothProfileServiceProviderImpl> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothProfileServiceProviderImpl);
 };
 
 BluetoothProfileServiceProvider::BluetoothProfileServiceProvider() = default;
diff --git a/device/bluetooth/dbus/bluetooth_profile_service_provider.h b/device/bluetooth/dbus/bluetooth_profile_service_provider.h
index c5417f06..dfa23a1 100644
--- a/device/bluetooth/dbus/bluetooth_profile_service_provider.h
+++ b/device/bluetooth/dbus/bluetooth_profile_service_provider.h
@@ -91,6 +91,11 @@
     virtual void Cancel() = 0;
   };
 
+  BluetoothProfileServiceProvider(const BluetoothProfileServiceProvider&) =
+      delete;
+  BluetoothProfileServiceProvider& operator=(
+      const BluetoothProfileServiceProvider&) = delete;
+
   virtual ~BluetoothProfileServiceProvider();
 
   // Creates the instance where |bus| is the D-Bus bus connection to export
@@ -104,9 +109,6 @@
 
  protected:
   BluetoothProfileServiceProvider();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(BluetoothProfileServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/bluez_dbus_manager.h b/device/bluetooth/dbus/bluez_dbus_manager.h
index c38d004..9608ab3 100644
--- a/device/bluetooth/dbus/bluez_dbus_manager.h
+++ b/device/bluetooth/dbus/bluez_dbus_manager.h
@@ -186,6 +186,9 @@
 
 class DEVICE_BLUETOOTH_EXPORT BluezDBusManagerSetter {
  public:
+  BluezDBusManagerSetter(const BluezDBusManagerSetter&) = delete;
+  BluezDBusManagerSetter& operator=(const BluezDBusManagerSetter&) = delete;
+
   ~BluezDBusManagerSetter();
 
   void SetBluetoothAdapterClient(
@@ -227,8 +230,6 @@
   friend class BluezDBusManager;
 
   BluezDBusManagerSetter();
-
-  DISALLOW_COPY_AND_ASSIGN(BluezDBusManagerSetter);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h
index b42b2fe..f5f6572 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_application_service_provider.h
@@ -31,6 +31,12 @@
       const dbus::ObjectPath& object_path,
       const std::map<dbus::ObjectPath, BluetoothLocalGattServiceBlueZ*>&
           services);
+
+  FakeBluetoothGattApplicationServiceProvider(
+      const FakeBluetoothGattApplicationServiceProvider&) = delete;
+  FakeBluetoothGattApplicationServiceProvider& operator=(
+      const FakeBluetoothGattApplicationServiceProvider&) = delete;
+
   ~FakeBluetoothGattApplicationServiceProvider() override;
 
   const dbus::ObjectPath& object_path() const { return object_path_; }
@@ -38,8 +44,6 @@
  private:
   // D-Bus object path of the fake GATT service.
   dbus::ObjectPath object_path_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattApplicationServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h
index 7d20bed..255a072 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_client.h
@@ -43,6 +43,12 @@
   };
 
   FakeBluetoothGattCharacteristicClient();
+
+  FakeBluetoothGattCharacteristicClient(
+      const FakeBluetoothGattCharacteristicClient&) = delete;
+  FakeBluetoothGattCharacteristicClient& operator=(
+      const FakeBluetoothGattCharacteristicClient&) = delete;
+
   ~FakeBluetoothGattCharacteristicClient() override;
 
   // DBusClient override.
@@ -205,8 +211,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<FakeBluetoothGattCharacteristicClient> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattCharacteristicClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
index 27ec2e3..5ccc7f1 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_characteristic_service_provider.h
@@ -31,6 +31,12 @@
       const std::string& uuid,
       const std::vector<std::string>& flags,
       const dbus::ObjectPath& service_path);
+
+  FakeBluetoothGattCharacteristicServiceProvider(
+      const FakeBluetoothGattCharacteristicServiceProvider&) = delete;
+  FakeBluetoothGattCharacteristicServiceProvider& operator=(
+      const FakeBluetoothGattCharacteristicServiceProvider&) = delete;
+
   ~FakeBluetoothGattCharacteristicServiceProvider() override;
 
   // BluetoothGattCharacteristicServiceProvider override.
@@ -82,8 +88,6 @@
 
   // The delegate that method calls are passed on to.
   std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattCharacteristicServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h
index ef30c5ec..fb8edbc 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_client.h
@@ -39,6 +39,12 @@
   };
 
   FakeBluetoothGattDescriptorClient();
+
+  FakeBluetoothGattDescriptorClient(const FakeBluetoothGattDescriptorClient&) =
+      delete;
+  FakeBluetoothGattDescriptorClient& operator=(
+      const FakeBluetoothGattDescriptorClient&) = delete;
+
   ~FakeBluetoothGattDescriptorClient() override;
 
   // DBusClient override.
@@ -99,8 +105,6 @@
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<FakeBluetoothGattDescriptorClient> weak_ptr_factory_{
       this};
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
index a1aa918..aaf4f6d 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_descriptor_service_provider.h
@@ -31,6 +31,12 @@
       const std::string& uuid,
       const std::vector<std::string>& flags,
       const dbus::ObjectPath& characteristic_path);
+
+  FakeBluetoothGattDescriptorServiceProvider(
+      const FakeBluetoothGattDescriptorServiceProvider&) = delete;
+  FakeBluetoothGattDescriptorServiceProvider& operator=(
+      const FakeBluetoothGattDescriptorServiceProvider&) = delete;
+
   ~FakeBluetoothGattDescriptorServiceProvider() override;
 
   // BluetoothGattDescriptorServiceProvider override.
@@ -69,8 +75,6 @@
 
   // The delegate that method calls are passed on to.
   std::unique_ptr<BluetoothGattAttributeValueDelegate> delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattDescriptorServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
index 7431a0f..d60fcfc00 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_manager_client.h
@@ -34,6 +34,12 @@
     : public BluetoothGattManagerClient {
  public:
   FakeBluetoothGattManagerClient();
+
+  FakeBluetoothGattManagerClient(const FakeBluetoothGattManagerClient&) =
+      delete;
+  FakeBluetoothGattManagerClient& operator=(
+      const FakeBluetoothGattManagerClient&) = delete;
+
   ~FakeBluetoothGattManagerClient() override;
 
   // DBusClient override.
@@ -123,8 +129,6 @@
   ServiceMap service_map_;
   CharacteristicMap characteristic_map_;
   DescriptorMap descriptor_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattManagerClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
index cb5f2be6..a0aa535 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_client.h
@@ -38,6 +38,12 @@
   };
 
   FakeBluetoothGattServiceClient();
+
+  FakeBluetoothGattServiceClient(const FakeBluetoothGattServiceClient&) =
+      delete;
+  FakeBluetoothGattServiceClient& operator=(
+      const FakeBluetoothGattServiceClient&) = delete;
+
   ~FakeBluetoothGattServiceClient() override;
 
   // DBusClient override.
@@ -121,8 +127,6 @@
   // Note: This should remain the last member so it'll be destroyed and
   // invalidate its weak pointers before any other members are destroyed.
   base::WeakPtrFactory<FakeBluetoothGattServiceClient> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
index 7337a946..bfa85bc4 100644
--- a/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_gatt_service_service_provider.h
@@ -25,6 +25,12 @@
       const dbus::ObjectPath& object_path,
       const std::string& uuid,
       const std::vector<dbus::ObjectPath>& includes);
+
+  FakeBluetoothGattServiceServiceProvider(
+      const FakeBluetoothGattServiceServiceProvider&) = delete;
+  FakeBluetoothGattServiceServiceProvider& operator=(
+      const FakeBluetoothGattServiceServiceProvider&) = delete;
+
   ~FakeBluetoothGattServiceServiceProvider() override;
 
   const dbus::ObjectPath& object_path() const override;
@@ -39,8 +45,6 @@
 
   // List of included GATT services.
   std::vector<dbus::ObjectPath> includes_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothGattServiceServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_input_client.h b/device/bluetooth/dbus/fake_bluetooth_input_client.h
index b4bf3db..cb9a1dd8 100644
--- a/device/bluetooth/dbus/fake_bluetooth_input_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_input_client.h
@@ -36,6 +36,10 @@
   };
 
   FakeBluetoothInputClient();
+
+  FakeBluetoothInputClient(const FakeBluetoothInputClient&) = delete;
+  FakeBluetoothInputClient& operator=(const FakeBluetoothInputClient&) = delete;
+
   ~FakeBluetoothInputClient() override;
 
   // BluetoothInputClient overrides
@@ -58,8 +62,6 @@
 
   // List of observers interested in event notifications from us.
   base::ObserverList<Observer>::Unchecked observers_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothInputClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h
index 59c819e..0aae329 100644
--- a/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_le_advertisement_service_provider.h
@@ -23,6 +23,12 @@
   FakeBluetoothLEAdvertisementServiceProvider(
       const dbus::ObjectPath& object_path,
       Delegate* delegate);
+
+  FakeBluetoothLEAdvertisementServiceProvider(
+      const FakeBluetoothLEAdvertisementServiceProvider&) = delete;
+  FakeBluetoothLEAdvertisementServiceProvider& operator=(
+      const FakeBluetoothLEAdvertisementServiceProvider&) = delete;
+
   ~FakeBluetoothLEAdvertisementServiceProvider() override;
 
   // Each of these calls the equivalent
@@ -39,8 +45,6 @@
   // passed to generate the reply. |delegate_| is generally the object that
   // owns this one, and must outlive it.
   Delegate* delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h
index 633b87c..a22529b 100644
--- a/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_le_advertising_manager_client.h
@@ -28,6 +28,12 @@
     : public BluetoothLEAdvertisingManagerClient {
  public:
   FakeBluetoothLEAdvertisingManagerClient();
+
+  FakeBluetoothLEAdvertisingManagerClient(
+      const FakeBluetoothLEAdvertisingManagerClient&) = delete;
+  FakeBluetoothLEAdvertisingManagerClient& operator=(
+      const FakeBluetoothLEAdvertisingManagerClient&) = delete;
+
   ~FakeBluetoothLEAdvertisingManagerClient() override;
 
   // DBusClient overrides:
@@ -80,8 +86,6 @@
 
   // Holds currently registered advertisements.
   std::vector<dbus::ObjectPath> currently_registered_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisingManagerClient);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h
index 383c224..f40ddc6 100644
--- a/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h
+++ b/device/bluetooth/dbus/fake_bluetooth_profile_service_provider.h
@@ -24,6 +24,12 @@
  public:
   FakeBluetoothProfileServiceProvider(const dbus::ObjectPath& object_path,
                                       Delegate* delegate);
+
+  FakeBluetoothProfileServiceProvider(
+      const FakeBluetoothProfileServiceProvider&) = delete;
+  FakeBluetoothProfileServiceProvider& operator=(
+      const FakeBluetoothProfileServiceProvider&) = delete;
+
   ~FakeBluetoothProfileServiceProvider() override;
 
   // Each of these calls the equivalent
@@ -50,8 +56,6 @@
   // passed to generate the reply. |delegate_| is generally the object that
   // owns this one, and must outlive it.
   Delegate* delegate_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothProfileServiceProvider);
 };
 
 }  // namespace bluez
diff --git a/device/bluetooth/device.h b/device/bluetooth/device.h
index d31bf00..6ebc0f9 100644
--- a/device/bluetooth/device.h
+++ b/device/bluetooth/device.h
@@ -32,6 +32,9 @@
 // instance closes the binding which causes the instance to be deleted.
 class Device : public mojom::Device, public device::BluetoothAdapter::Observer {
  public:
+  Device(const Device&) = delete;
+  Device& operator=(const Device&) = delete;
+
   ~Device() override;
 
   static void Create(
@@ -125,8 +128,6 @@
   std::vector<base::OnceClosure> pending_services_requests_;
 
   base::WeakPtrFactory<Device> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(Device);
 };
 
 }  // namespace bluetooth
diff --git a/device/bluetooth/discovery_session.h b/device/bluetooth/discovery_session.h
index c30c0d51..7cf5f1c3 100644
--- a/device/bluetooth/discovery_session.h
+++ b/device/bluetooth/discovery_session.h
@@ -24,6 +24,10 @@
  public:
   explicit DiscoverySession(
       std::unique_ptr<device::BluetoothDiscoverySession> session);
+
+  DiscoverySession(const DiscoverySession&) = delete;
+  DiscoverySession& operator=(const DiscoverySession&) = delete;
+
   ~DiscoverySession() override;
 
   // mojom::DiscoverySession overrides:
@@ -35,8 +39,6 @@
   std::unique_ptr<device::BluetoothDiscoverySession> discovery_session_;
 
   base::WeakPtrFactory<DiscoverySession> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(DiscoverySession);
 };
 
 }  // namespace bluetooth
diff --git a/device/bluetooth/test/bluetooth_test.h b/device/bluetooth/test/bluetooth_test.h
index c911a26..ef00671 100644
--- a/device/bluetooth/test/bluetooth_test.h
+++ b/device/bluetooth/test/bluetooth_test.h
@@ -70,6 +70,10 @@
   struct LowEnergyDeviceData {
     LowEnergyDeviceData();
     LowEnergyDeviceData(LowEnergyDeviceData&& data);
+
+    LowEnergyDeviceData(const LowEnergyDeviceData&) = delete;
+    LowEnergyDeviceData& operator=(const LowEnergyDeviceData&) = delete;
+
     ~LowEnergyDeviceData();
 
     absl::optional<std::string> name;
@@ -81,8 +85,6 @@
     BluetoothDevice::ServiceDataMap service_data;
     BluetoothDevice::ManufacturerDataMap manufacturer_data;
     BluetoothTransport transport = BLUETOOTH_TRANSPORT_LE;
-
-    DISALLOW_COPY_AND_ASSIGN(LowEnergyDeviceData);
   };
 
   static const char kTestAdapterName[];
diff --git a/device/bluetooth/test/bluetooth_test_cast.h b/device/bluetooth/test/bluetooth_test_cast.h
index e0b871ef..e17ff54 100644
--- a/device/bluetooth/test/bluetooth_test_cast.h
+++ b/device/bluetooth/test/bluetooth_test_cast.h
@@ -25,6 +25,10 @@
 class BluetoothTestCast : public BluetoothTestBase {
  public:
   BluetoothTestCast();
+
+  BluetoothTestCast(const BluetoothTestCast&) = delete;
+  BluetoothTestCast& operator=(const BluetoothTestCast&) = delete;
+
   ~BluetoothTestCast() override;
 
   // BluetoothTestBase overrides:
@@ -44,8 +48,6 @@
 
   const std::unique_ptr<GattClientManager> gatt_client_manager_;
   ::chromecast::bluetooth::MockLeScanManager le_scan_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothTestCast);
 };
 
 // Defines common test fixture name. Use TEST_F(BluetoothTest, YourTestName).
diff --git a/device/bluetooth/test/bluetooth_test_win.h b/device/bluetooth/test/bluetooth_test_win.h
index 6b69788..c155876a 100644
--- a/device/bluetooth/test/bluetooth_test_win.h
+++ b/device/bluetooth/test/bluetooth_test_win.h
@@ -163,6 +163,10 @@
       public ::testing::WithParamInterface<BluetoothTestWinrtParam> {
  public:
   BluetoothTestWinrt();
+
+  BluetoothTestWinrt(const BluetoothTestWinrt&) = delete;
+  BluetoothTestWinrt& operator=(const BluetoothTestWinrt&) = delete;
+
   ~BluetoothTestWinrt() override;
 
   bool UsesNewBleImplementation() const;
@@ -263,8 +267,6 @@
  private:
   base::test::ScopedFeatureList scoped_feature_list_;
   absl::optional<base::win::ScopedWinrtInitializer> scoped_winrt_initializer_;
-
-  DISALLOW_COPY_AND_ASSIGN(BluetoothTestWinrt);
 };
 
 using BluetoothTestWinrtOnly = BluetoothTestWinrt;
diff --git a/device/bluetooth/test/fake_bluetooth_adapter_winrt.h b/device/bluetooth/test/fake_bluetooth_adapter_winrt.h
index 8e290a4..fb3b02f 100644
--- a/device/bluetooth/test/fake_bluetooth_adapter_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_adapter_winrt.h
@@ -26,6 +26,11 @@
   FakeBluetoothAdapterWinrt(
       base::StringPiece address,
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Radios::IRadio> radio);
+
+  FakeBluetoothAdapterWinrt(const FakeBluetoothAdapterWinrt&) = delete;
+  FakeBluetoothAdapterWinrt& operator=(const FakeBluetoothAdapterWinrt&) =
+      delete;
+
   ~FakeBluetoothAdapterWinrt() override;
 
   static uint64_t ToRawBluetoothAddress(base::StringPiece address);
@@ -47,8 +52,6 @@
  private:
   uint64_t raw_address_;
   Microsoft::WRL::ComPtr<ABI::Windows::Devices::Radios::IRadio> radio_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothAdapterWinrt);
 };
 
 class FakeBluetoothAdapterStaticsWinrt
@@ -60,6 +63,12 @@
   explicit FakeBluetoothAdapterStaticsWinrt(
       Microsoft::WRL::ComPtr<
           ABI::Windows::Devices::Bluetooth::IBluetoothAdapter> default_adapter);
+
+  FakeBluetoothAdapterStaticsWinrt(const FakeBluetoothAdapterStaticsWinrt&) =
+      delete;
+  FakeBluetoothAdapterStaticsWinrt& operator=(
+      const FakeBluetoothAdapterStaticsWinrt&) = delete;
+
   ~FakeBluetoothAdapterStaticsWinrt() override;
 
   // IBluetoothAdapterStatics:
@@ -77,8 +86,6 @@
  private:
   Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::IBluetoothAdapter>
       default_adapter_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothAdapterStaticsWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_bluetooth_le_advertisement_data_section_winrt.h b/device/bluetooth/test/fake_bluetooth_le_advertisement_data_section_winrt.h
index bc0f5da..bd20106 100644
--- a/device/bluetooth/test/fake_bluetooth_le_advertisement_data_section_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_advertisement_data_section_winrt.h
@@ -25,6 +25,12 @@
  public:
   explicit FakeBluetoothLEAdvertisementDataSectionWinrt(
       std::vector<uint8_t> data);
+
+  FakeBluetoothLEAdvertisementDataSectionWinrt(
+      const FakeBluetoothLEAdvertisementDataSectionWinrt&) = delete;
+  FakeBluetoothLEAdvertisementDataSectionWinrt& operator=(
+      const FakeBluetoothLEAdvertisementDataSectionWinrt&) = delete;
+
   ~FakeBluetoothLEAdvertisementDataSectionWinrt() override;
 
   // IBluetoothLEAdvertisementDataSection:
@@ -37,8 +43,6 @@
 
  private:
   std::vector<uint8_t> data_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementDataSectionWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_bluetooth_le_advertisement_publisher_winrt.h b/device/bluetooth/test/fake_bluetooth_le_advertisement_publisher_winrt.h
index 82acd52f..95c7f115 100644
--- a/device/bluetooth/test/fake_bluetooth_le_advertisement_publisher_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_advertisement_publisher_winrt.h
@@ -24,6 +24,12 @@
   explicit FakeBluetoothLEAdvertisementPublisherWinrt(
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::Advertisement::
                                  IBluetoothLEAdvertisement> advertisement);
+
+  FakeBluetoothLEAdvertisementPublisherWinrt(
+      const FakeBluetoothLEAdvertisementPublisherWinrt&) = delete;
+  FakeBluetoothLEAdvertisementPublisherWinrt& operator=(
+      const FakeBluetoothLEAdvertisementPublisherWinrt&) = delete;
+
   ~FakeBluetoothLEAdvertisementPublisherWinrt() override;
 
   // IBluetoothLEAdvertisementPublisher:
@@ -65,8 +71,6 @@
       ABI::Windows::Devices::Bluetooth::Advertisement::
           BluetoothLEAdvertisementPublisherStatusChangedEventArgs*>>
       handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementPublisherWinrt);
 };
 
 class FakeBluetoothLEAdvertisementPublisherFactoryWinrt
@@ -77,6 +81,12 @@
               IBluetoothLEAdvertisementPublisherFactory> {
  public:
   FakeBluetoothLEAdvertisementPublisherFactoryWinrt();
+
+  FakeBluetoothLEAdvertisementPublisherFactoryWinrt(
+      const FakeBluetoothLEAdvertisementPublisherFactoryWinrt&) = delete;
+  FakeBluetoothLEAdvertisementPublisherFactoryWinrt& operator=(
+      const FakeBluetoothLEAdvertisementPublisherFactoryWinrt&) = delete;
+
   ~FakeBluetoothLEAdvertisementPublisherFactoryWinrt() override;
 
   // IBluetoothLEAdvertisementPublisherFactory:
@@ -85,9 +95,6 @@
           IBluetoothLEAdvertisement* advertisement,
       ABI::Windows::Devices::Bluetooth::Advertisement::
           IBluetoothLEAdvertisementPublisher** value) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementPublisherFactoryWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_bluetooth_le_advertisement_received_event_args_winrt.h b/device/bluetooth/test/fake_bluetooth_le_advertisement_received_event_args_winrt.h
index 91929a83..8e06c5a1 100644
--- a/device/bluetooth/test/fake_bluetooth_le_advertisement_received_event_args_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_advertisement_received_event_args_winrt.h
@@ -27,6 +27,12 @@
       base::StringPiece address,
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::Advertisement::
                                  IBluetoothLEAdvertisement> advertisement);
+
+  FakeBluetoothLEAdvertisementReceivedEventArgsWinrt(
+      const FakeBluetoothLEAdvertisementReceivedEventArgsWinrt&) = delete;
+  FakeBluetoothLEAdvertisementReceivedEventArgsWinrt& operator=(
+      const FakeBluetoothLEAdvertisementReceivedEventArgsWinrt&) = delete;
+
   ~FakeBluetoothLEAdvertisementReceivedEventArgsWinrt() override;
 
   // IBluetoothLEAdvertisementReceivedEventArgs:
@@ -47,8 +53,6 @@
   Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::Advertisement::
                              IBluetoothLEAdvertisement>
       advertisement_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementReceivedEventArgsWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_bluetooth_le_advertisement_watcher_winrt.h b/device/bluetooth/test/fake_bluetooth_le_advertisement_watcher_winrt.h
index d6f2107..dcc9d80 100644
--- a/device/bluetooth/test/fake_bluetooth_le_advertisement_watcher_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_advertisement_watcher_winrt.h
@@ -24,6 +24,12 @@
               IBluetoothLEAdvertisementWatcher> {
  public:
   FakeBluetoothLEAdvertisementWatcherWinrt();
+
+  FakeBluetoothLEAdvertisementWatcherWinrt(
+      const FakeBluetoothLEAdvertisementWatcherWinrt&) = delete;
+  FakeBluetoothLEAdvertisementWatcherWinrt& operator=(
+      const FakeBluetoothLEAdvertisementWatcherWinrt&) = delete;
+
   ~FakeBluetoothLEAdvertisementWatcherWinrt() override;
 
   // IBluetoothLEAdvertisementWatcher:
@@ -98,8 +104,6 @@
       ABI::Windows::Devices::Bluetooth::Advertisement::
           BluetoothLEAdvertisementWatcherStoppedEventArgs*>>
       stopped_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementWatcherWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_bluetooth_le_advertisement_winrt.h b/device/bluetooth/test/fake_bluetooth_le_advertisement_winrt.h
index d3da39e..7c439da 100644
--- a/device/bluetooth/test/fake_bluetooth_le_advertisement_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_advertisement_winrt.h
@@ -34,6 +34,12 @@
       absl::optional<int8_t> tx_power,
       BluetoothDevice::ServiceDataMap service_data,
       BluetoothDevice::ManufacturerDataMap manufacturer_data);
+
+  FakeBluetoothLEAdvertisementWinrt(const FakeBluetoothLEAdvertisementWinrt&) =
+      delete;
+  FakeBluetoothLEAdvertisementWinrt& operator=(
+      const FakeBluetoothLEAdvertisementWinrt&) = delete;
+
   ~FakeBluetoothLEAdvertisementWinrt() override;
 
   // IBluetoothLEAdvertisement:
@@ -73,8 +79,6 @@
   absl::optional<int8_t> tx_power_;
   BluetoothDevice::ServiceDataMap service_data_;
   BluetoothDevice::ManufacturerDataMap manufacturer_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEAdvertisementWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_bluetooth_le_device_winrt.h b/device/bluetooth/test/fake_bluetooth_le_device_winrt.h
index 8f74f09..bedd4be 100644
--- a/device/bluetooth/test/fake_bluetooth_le_device_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_device_winrt.h
@@ -36,6 +36,11 @@
           ABI::Windows::Foundation::IClosable> {
  public:
   explicit FakeBluetoothLEDeviceWinrt(BluetoothTestWinrt* bluetooth_test_winrt);
+
+  FakeBluetoothLEDeviceWinrt(const FakeBluetoothLEDeviceWinrt&) = delete;
+  FakeBluetoothLEDeviceWinrt& operator=(const FakeBluetoothLEDeviceWinrt&) =
+      delete;
+
   ~FakeBluetoothLEDeviceWinrt() override;
 
   // IBluetoothLEDevice:
@@ -184,8 +189,6 @@
       ABI::Windows::Devices::Bluetooth::BluetoothLEDevice*,
       IInspectable*>>
       name_changed_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEDeviceWinrt);
 };
 
 class FakeBluetoothLEDeviceStaticsWinrt
@@ -196,6 +199,12 @@
  public:
   explicit FakeBluetoothLEDeviceStaticsWinrt(
       BluetoothTestWinrt* bluetooth_test_winrt);
+
+  FakeBluetoothLEDeviceStaticsWinrt(const FakeBluetoothLEDeviceStaticsWinrt&) =
+      delete;
+  FakeBluetoothLEDeviceStaticsWinrt& operator=(
+      const FakeBluetoothLEDeviceStaticsWinrt&) = delete;
+
   ~FakeBluetoothLEDeviceStaticsWinrt() override;
 
   // IBluetoothLEDeviceStatics:
@@ -213,8 +222,6 @@
 
  private:
   BluetoothTestWinrt* bluetooth_test_winrt_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEDeviceStaticsWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_bluetooth_le_manufacturer_data_winrt.h b/device/bluetooth/test/fake_bluetooth_le_manufacturer_data_winrt.h
index 77238793..2e2f47f66 100644
--- a/device/bluetooth/test/fake_bluetooth_le_manufacturer_data_winrt.h
+++ b/device/bluetooth/test/fake_bluetooth_le_manufacturer_data_winrt.h
@@ -29,6 +29,12 @@
   FakeBluetoothLEManufacturerData(
       uint16_t company_id,
       Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> data);
+
+  FakeBluetoothLEManufacturerData(const FakeBluetoothLEManufacturerData&) =
+      delete;
+  FakeBluetoothLEManufacturerData& operator=(
+      const FakeBluetoothLEManufacturerData&) = delete;
+
   ~FakeBluetoothLEManufacturerData() override;
 
   // IBluetoothLEManufacturerData:
@@ -42,8 +48,6 @@
  private:
   uint16_t company_id_;
   Microsoft::WRL::ComPtr<ABI::Windows::Storage::Streams::IBuffer> data_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEManufacturerData);
 };
 
 class FakeBluetoothLEManufacturerDataFactory
@@ -54,6 +58,12 @@
               IBluetoothLEManufacturerDataFactory> {
  public:
   FakeBluetoothLEManufacturerDataFactory();
+
+  FakeBluetoothLEManufacturerDataFactory(
+      const FakeBluetoothLEManufacturerDataFactory&) = delete;
+  FakeBluetoothLEManufacturerDataFactory& operator=(
+      const FakeBluetoothLEManufacturerDataFactory&) = delete;
+
   ~FakeBluetoothLEManufacturerDataFactory() override;
 
   // IBluetoothLEManufacturerDataFactory:
@@ -61,9 +71,6 @@
                         ABI::Windows::Storage::Streams::IBuffer* data,
                         ABI::Windows::Devices::Bluetooth::Advertisement::
                             IBluetoothLEManufacturerData** value) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FakeBluetoothLEManufacturerDataFactory);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_device_information_custom_pairing_winrt.h b/device/bluetooth/test/fake_device_information_custom_pairing_winrt.h
index 8a94d2f6..9b7602b 100644
--- a/device/bluetooth/test/fake_device_information_custom_pairing_winrt.h
+++ b/device/bluetooth/test/fake_device_information_custom_pairing_winrt.h
@@ -26,6 +26,12 @@
   FakeDeviceInformationCustomPairingWinrt(
       Microsoft::WRL::ComPtr<FakeDeviceInformationPairingWinrt> pairing,
       std::string pin);
+
+  FakeDeviceInformationCustomPairingWinrt(
+      const FakeDeviceInformationCustomPairingWinrt&) = delete;
+  FakeDeviceInformationCustomPairingWinrt& operator=(
+      const FakeDeviceInformationCustomPairingWinrt&) = delete;
+
   ~FakeDeviceInformationCustomPairingWinrt() override;
 
   // IDeviceInformationCustomPairing:
@@ -78,8 +84,6 @@
       ABI::Windows::Devices::Enumeration::DeviceInformationCustomPairing*,
       ABI::Windows::Devices::Enumeration::DevicePairingRequestedEventArgs*>>
       pairing_requested_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationCustomPairingWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_device_information_pairing_winrt.h b/device/bluetooth/test/fake_device_information_pairing_winrt.h
index 14a542d9..bdaa33f 100644
--- a/device/bluetooth/test/fake_device_information_pairing_winrt.h
+++ b/device/bluetooth/test/fake_device_information_pairing_winrt.h
@@ -24,6 +24,12 @@
  public:
   explicit FakeDeviceInformationPairingWinrt(bool is_paired);
   explicit FakeDeviceInformationPairingWinrt(std::string pin);
+
+  FakeDeviceInformationPairingWinrt(const FakeDeviceInformationPairingWinrt&) =
+      delete;
+  FakeDeviceInformationPairingWinrt& operator=(
+      const FakeDeviceInformationPairingWinrt&) = delete;
+
   ~FakeDeviceInformationPairingWinrt() override;
 
   // IDeviceInformationPairing:
@@ -67,8 +73,6 @@
   Microsoft::WRL::ComPtr<
       ABI::Windows::Devices::Enumeration::IDeviceInformationCustomPairing>
       custom_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationPairingWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_device_information_winrt.h b/device/bluetooth/test/fake_device_information_winrt.h
index b6891fc..3776285 100644
--- a/device/bluetooth/test/fake_device_information_winrt.h
+++ b/device/bluetooth/test/fake_device_information_winrt.h
@@ -32,6 +32,11 @@
       Microsoft::WRL::ComPtr<
           ABI::Windows::Devices::Enumeration::IDeviceInformationPairing>
           pairing);
+
+  FakeDeviceInformationWinrt(const FakeDeviceInformationWinrt&) = delete;
+  FakeDeviceInformationWinrt& operator=(const FakeDeviceInformationWinrt&) =
+      delete;
+
   ~FakeDeviceInformationWinrt() override;
 
   // IDeviceInformation:
@@ -69,8 +74,6 @@
   Microsoft::WRL::ComPtr<
       ABI::Windows::Devices::Enumeration::IDeviceInformationPairing>
       pairing_ = Microsoft::WRL::Make<FakeDeviceInformationPairingWinrt>(false);
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationWinrt);
 };
 
 class FakeDeviceInformationStaticsWinrt
@@ -83,6 +86,12 @@
       Microsoft::WRL::ComPtr<
           ABI::Windows::Devices::Enumeration::IDeviceInformation>
           device_information);
+
+  FakeDeviceInformationStaticsWinrt(const FakeDeviceInformationStaticsWinrt&) =
+      delete;
+  FakeDeviceInformationStaticsWinrt& operator=(
+      const FakeDeviceInformationStaticsWinrt&) = delete;
+
   ~FakeDeviceInformationStaticsWinrt() override;
 
   // IDeviceInformationStatics:
@@ -138,8 +147,6 @@
  private:
   Microsoft::WRL::ComPtr<ABI::Windows::Devices::Enumeration::IDeviceInformation>
       device_information_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDeviceInformationStaticsWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.cc b/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.cc
index 854122f..89f0c24 100644
--- a/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.cc
+++ b/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.cc
@@ -30,6 +30,10 @@
   explicit FakeDeferral(
       ComPtr<FakeDevicePairingRequestedEventArgsWinrt> pairing_requested)
       : pairing_requested_(std::move(pairing_requested)) {}
+
+  FakeDeferral(const FakeDeferral&) = delete;
+  FakeDeferral& operator=(const FakeDeferral&) = delete;
+
   ~FakeDeferral() override = default;
 
   // IDeferral:
@@ -40,8 +44,6 @@
 
  private:
   ComPtr<FakeDevicePairingRequestedEventArgsWinrt> pairing_requested_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDeferral);
 };
 
 }  // namespace
diff --git a/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.h b/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.h
index b2f8599..d8ab4f4 100644
--- a/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.h
+++ b/device/bluetooth/test/fake_device_pairing_requested_event_args_winrt.h
@@ -24,6 +24,12 @@
   explicit FakeDevicePairingRequestedEventArgsWinrt(
       Microsoft::WRL::ComPtr<FakeDeviceInformationCustomPairingWinrt>
           custom_pairing);
+
+  FakeDevicePairingRequestedEventArgsWinrt(
+      const FakeDevicePairingRequestedEventArgsWinrt&) = delete;
+  FakeDevicePairingRequestedEventArgsWinrt& operator=(
+      const FakeDevicePairingRequestedEventArgsWinrt&) = delete;
+
   ~FakeDevicePairingRequestedEventArgsWinrt() override;
 
   // IDevicePairingRequestedEventArgs:
@@ -42,8 +48,6 @@
  private:
   Microsoft::WRL::ComPtr<FakeDeviceInformationCustomPairingWinrt>
       custom_pairing_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDevicePairingRequestedEventArgsWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_device_pairing_result_winrt.h b/device/bluetooth/test/fake_device_pairing_result_winrt.h
index 55a8400..7b66d7f1 100644
--- a/device/bluetooth/test/fake_device_pairing_result_winrt.h
+++ b/device/bluetooth/test/fake_device_pairing_result_winrt.h
@@ -20,6 +20,11 @@
  public:
   explicit FakeDevicePairingResultWinrt(
       ABI::Windows::Devices::Enumeration::DevicePairingResultStatus status);
+
+  FakeDevicePairingResultWinrt(const FakeDevicePairingResultWinrt&) = delete;
+  FakeDevicePairingResultWinrt& operator=(const FakeDevicePairingResultWinrt&) =
+      delete;
+
   ~FakeDevicePairingResultWinrt() override;
 
   // IDevicePairingResult:
@@ -32,8 +37,6 @@
 
  private:
   ABI::Windows::Devices::Enumeration::DevicePairingResultStatus status_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDevicePairingResultWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_device_watcher_winrt.h b/device/bluetooth/test/fake_device_watcher_winrt.h
index 5ecbd4f..65bcfbf4 100644
--- a/device/bluetooth/test/fake_device_watcher_winrt.h
+++ b/device/bluetooth/test/fake_device_watcher_winrt.h
@@ -21,6 +21,10 @@
           ABI::Windows::Devices::Enumeration::IDeviceWatcher> {
  public:
   FakeDeviceWatcherWinrt();
+
+  FakeDeviceWatcherWinrt(const FakeDeviceWatcherWinrt&) = delete;
+  FakeDeviceWatcherWinrt& operator=(const FakeDeviceWatcherWinrt&) = delete;
+
   ~FakeDeviceWatcherWinrt() override;
 
   // IDeviceWatcher:
@@ -82,8 +86,6 @@
       ABI::Windows::Devices::Enumeration::DeviceWatcher*,
       IInspectable*>>
       enumerated_handler_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeDeviceWatcherWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_characteristic_winrt.h b/device/bluetooth/test/fake_gatt_characteristic_winrt.h
index 2c08f74..f2d146f 100644
--- a/device/bluetooth/test/fake_gatt_characteristic_winrt.h
+++ b/device/bluetooth/test/fake_gatt_characteristic_winrt.h
@@ -38,6 +38,10 @@
                               base::StringPiece uuid,
                               uint16_t attribute_handle);
 
+  FakeGattCharacteristicWinrt(const FakeGattCharacteristicWinrt&) = delete;
+  FakeGattCharacteristicWinrt& operator=(const FakeGattCharacteristicWinrt&) =
+      delete;
+
   ~FakeGattCharacteristicWinrt() override;
 
   // IGattCharacteristic:
@@ -192,8 +196,6 @@
   std::vector<Microsoft::WRL::ComPtr<FakeGattDescriptorWinrt>>
       fake_descriptors_;
   uint16_t last_descriptor_attribute_handle_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattCharacteristicWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_characteristics_result_winrt.h b/device/bluetooth/test/fake_gatt_characteristics_result_winrt.h
index c645372c..5bb2e3f 100644
--- a/device/bluetooth/test/fake_gatt_characteristics_result_winrt.h
+++ b/device/bluetooth/test/fake_gatt_characteristics_result_winrt.h
@@ -32,6 +32,12 @@
   explicit FakeGattCharacteristicsResultWinrt(
       const std::vector<Microsoft::WRL::ComPtr<FakeGattCharacteristicWinrt>>&
           fake_characteristics);
+
+  FakeGattCharacteristicsResultWinrt(
+      const FakeGattCharacteristicsResultWinrt&) = delete;
+  FakeGattCharacteristicsResultWinrt& operator=(
+      const FakeGattCharacteristicsResultWinrt&) = delete;
+
   ~FakeGattCharacteristicsResultWinrt() override;
 
   // IGattCharacteristicsResult:
@@ -50,8 +56,6 @@
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                  GenericAttributeProfile::IGattCharacteristic>>
       characteristics_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattCharacteristicsResultWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_descriptor_winrt.h b/device/bluetooth/test/fake_gatt_descriptor_winrt.h
index 6148a44..a4fa4b8 100644
--- a/device/bluetooth/test/fake_gatt_descriptor_winrt.h
+++ b/device/bluetooth/test/fake_gatt_descriptor_winrt.h
@@ -34,6 +34,10 @@
   FakeGattDescriptorWinrt(BluetoothTestWinrt* bluetooth_test_winrt,
                           base::StringPiece uuid,
                           uint16_t attribute_handle);
+
+  FakeGattDescriptorWinrt(const FakeGattDescriptorWinrt&) = delete;
+  FakeGattDescriptorWinrt& operator=(const FakeGattDescriptorWinrt&) = delete;
+
   ~FakeGattDescriptorWinrt() override;
 
   // IGattDescriptor:
@@ -88,8 +92,6 @@
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                  GenericAttributeProfile::IGattWriteResult>)>
       write_value_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattDescriptorWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_descriptors_result_winrt.h b/device/bluetooth/test/fake_gatt_descriptors_result_winrt.h
index 8c50b7d..df8f45c 100644
--- a/device/bluetooth/test/fake_gatt_descriptors_result_winrt.h
+++ b/device/bluetooth/test/fake_gatt_descriptors_result_winrt.h
@@ -31,6 +31,12 @@
   explicit FakeGattDescriptorsResultWinrt(
       const std::vector<Microsoft::WRL::ComPtr<FakeGattDescriptorWinrt>>&
           fake_descriptors);
+
+  FakeGattDescriptorsResultWinrt(const FakeGattDescriptorsResultWinrt&) =
+      delete;
+  FakeGattDescriptorsResultWinrt& operator=(
+      const FakeGattDescriptorsResultWinrt&) = delete;
+
   ~FakeGattDescriptorsResultWinrt() override;
 
   // IGattDescriptorsResult:
@@ -49,8 +55,6 @@
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                  GenericAttributeProfile::IGattDescriptor>>
       descriptors_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattDescriptorsResultWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_device_service_winrt.h b/device/bluetooth/test/fake_gatt_device_service_winrt.h
index d34ff29..ebb3d67 100644
--- a/device/bluetooth/test/fake_gatt_device_service_winrt.h
+++ b/device/bluetooth/test/fake_gatt_device_service_winrt.h
@@ -37,6 +37,11 @@
       base::StringPiece uuid,
       uint16_t attribute_handle,
       bool allowed);
+
+  FakeGattDeviceServiceWinrt(const FakeGattDeviceServiceWinrt&) = delete;
+  FakeGattDeviceServiceWinrt& operator=(const FakeGattDeviceServiceWinrt&) =
+      delete;
+
   ~FakeGattDeviceServiceWinrt() override;
 
   // IGattDeviceService:
@@ -128,8 +133,6 @@
   std::vector<Microsoft::WRL::ComPtr<FakeGattCharacteristicWinrt>>
       fake_characteristics_;
   uint16_t characteristic_attribute_handle_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattDeviceServiceWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_device_services_result_winrt.h b/device/bluetooth/test/fake_gatt_device_services_result_winrt.h
index a12f6b6d..f499eff 100644
--- a/device/bluetooth/test/fake_gatt_device_services_result_winrt.h
+++ b/device/bluetooth/test/fake_gatt_device_services_result_winrt.h
@@ -35,6 +35,12 @@
   explicit FakeGattDeviceServicesResultWinrt(
       const std::vector<Microsoft::WRL::ComPtr<FakeGattDeviceServiceWinrt>>&
           fake_services);
+
+  FakeGattDeviceServicesResultWinrt(const FakeGattDeviceServicesResultWinrt&) =
+      delete;
+  FakeGattDeviceServicesResultWinrt& operator=(
+      const FakeGattDeviceServicesResultWinrt&) = delete;
+
   ~FakeGattDeviceServicesResultWinrt() override;
 
   // IGattDeviceServicesResult:
@@ -55,8 +61,6 @@
       Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
                                  GenericAttributeProfile::IGattDeviceService>>
       services_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattDeviceServicesResultWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_read_result_winrt.h b/device/bluetooth/test/fake_gatt_read_result_winrt.h
index ebe2651..2eae5e8 100644
--- a/device/bluetooth/test/fake_gatt_read_result_winrt.h
+++ b/device/bluetooth/test/fake_gatt_read_result_winrt.h
@@ -29,6 +29,10 @@
   explicit FakeGattReadResultWinrt(
       BluetoothGattService::GattErrorCode error_code);
   explicit FakeGattReadResultWinrt(std::vector<uint8_t> data);
+
+  FakeGattReadResultWinrt(const FakeGattReadResultWinrt&) = delete;
+  FakeGattReadResultWinrt& operator=(const FakeGattReadResultWinrt&) = delete;
+
   ~FakeGattReadResultWinrt() override;
 
   // IGattReadResult:
@@ -48,8 +52,6 @@
           GenericAttributeProfile::GattCommunicationStatus_Success;
   std::vector<uint8_t> data_;
   uint8_t protocol_error_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattReadResultWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_value_changed_event_args_winrt.h b/device/bluetooth/test/fake_gatt_value_changed_event_args_winrt.h
index b329133..70aac891 100644
--- a/device/bluetooth/test/fake_gatt_value_changed_event_args_winrt.h
+++ b/device/bluetooth/test/fake_gatt_value_changed_event_args_winrt.h
@@ -24,6 +24,12 @@
               IGattValueChangedEventArgs> {
  public:
   explicit FakeGattValueChangedEventArgsWinrt(std::vector<uint8_t> value);
+
+  FakeGattValueChangedEventArgsWinrt(
+      const FakeGattValueChangedEventArgsWinrt&) = delete;
+  FakeGattValueChangedEventArgsWinrt& operator=(
+      const FakeGattValueChangedEventArgsWinrt&) = delete;
+
   ~FakeGattValueChangedEventArgsWinrt() override;
 
   // IGattValueChangedEventArgs:
@@ -34,8 +40,6 @@
 
  private:
   std::vector<uint8_t> value_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattValueChangedEventArgsWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_gatt_write_result_winrt.h b/device/bluetooth/test/fake_gatt_write_result_winrt.h
index 13b5fac..42369d84 100644
--- a/device/bluetooth/test/fake_gatt_write_result_winrt.h
+++ b/device/bluetooth/test/fake_gatt_write_result_winrt.h
@@ -25,6 +25,10 @@
   FakeGattWriteResultWinrt();
   explicit FakeGattWriteResultWinrt(
       BluetoothGattService::GattErrorCode error_code);
+
+  FakeGattWriteResultWinrt(const FakeGattWriteResultWinrt&) = delete;
+  FakeGattWriteResultWinrt& operator=(const FakeGattWriteResultWinrt&) = delete;
+
   ~FakeGattWriteResultWinrt() override;
 
   // IGattWriteResult:
@@ -39,8 +43,6 @@
       GattCommunicationStatus status_ = ABI::Windows::Devices::Bluetooth::
           GenericAttributeProfile::GattCommunicationStatus_Success;
   uint8_t protocol_error_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeGattWriteResultWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_peripheral.h b/device/bluetooth/test/fake_peripheral.h
index e9b1ee0..c4c20080 100644
--- a/device/bluetooth/test/fake_peripheral.h
+++ b/device/bluetooth/test/fake_peripheral.h
@@ -28,6 +28,10 @@
 class FakePeripheral : public device::BluetoothDevice {
  public:
   FakePeripheral(FakeCentral* fake_central, const std::string& address);
+
+  FakePeripheral(const FakePeripheral&) = delete;
+  FakePeripheral& operator=(const FakePeripheral&) = delete;
+
   ~FakePeripheral() override;
 
   // Changes the name of the device.
@@ -165,8 +169,6 @@
   // Mutable because IsGattServicesDiscoveryComplete needs to post a task but
   // is const.
   mutable base::WeakPtrFactory<FakePeripheral> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FakePeripheral);
 };
 
 }  // namespace bluetooth
diff --git a/device/bluetooth/test/fake_radio_winrt.h b/device/bluetooth/test/fake_radio_winrt.h
index 8f80961..d6221ba 100644
--- a/device/bluetooth/test/fake_radio_winrt.h
+++ b/device/bluetooth/test/fake_radio_winrt.h
@@ -23,6 +23,10 @@
           ABI::Windows::Devices::Radios::IRadio> {
  public:
   FakeRadioWinrt();
+
+  FakeRadioWinrt(const FakeRadioWinrt&) = delete;
+  FakeRadioWinrt& operator=(const FakeRadioWinrt&) = delete;
+
   ~FakeRadioWinrt() override;
 
   // IRadio:
@@ -66,8 +70,6 @@
   // TODO(https://crbug.com/878680): Implement SimulateAdapterPowerSuccess() and
   // clean this up.
   base::CancelableOnceClosure cancelable_closure_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeRadioWinrt);
 };
 
 class FakeRadioStaticsWinrt
@@ -77,6 +79,10 @@
           ABI::Windows::Devices::Radios::IRadioStatics> {
  public:
   FakeRadioStaticsWinrt();
+
+  FakeRadioStaticsWinrt(const FakeRadioStaticsWinrt&) = delete;
+  FakeRadioStaticsWinrt& operator=(const FakeRadioStaticsWinrt&) = delete;
+
   ~FakeRadioStaticsWinrt() override;
 
   void SimulateRequestAccessAsyncError(
@@ -100,8 +106,6 @@
  private:
   ABI::Windows::Devices::Radios::RadioAccessStatus access_status_ =
       ABI::Windows::Devices::Radios::RadioAccessStatus_Allowed;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeRadioStaticsWinrt);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/fake_read_response.h b/device/bluetooth/test/fake_read_response.h
index 81c85ef..bab0f8fe 100644
--- a/device/bluetooth/test/fake_read_response.h
+++ b/device/bluetooth/test/fake_read_response.h
@@ -18,6 +18,10 @@
  public:
   FakeReadResponse(uint16_t gatt_code,
                    const absl::optional<std::vector<uint8_t>>& value);
+
+  FakeReadResponse(const FakeReadResponse&) = delete;
+  FakeReadResponse& operator=(const FakeReadResponse&) = delete;
+
   ~FakeReadResponse();
 
   uint16_t gatt_code() { return gatt_code_; }
@@ -26,8 +30,6 @@
  private:
   uint16_t gatt_code_;
   absl::optional<std::vector<uint8_t>> value_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeReadResponse);
 };
 
 }  // namespace bluetooth
diff --git a/device/bluetooth/test/mock_bluetooth_adapter.h b/device/bluetooth/test/mock_bluetooth_adapter.h
index b6eacf4b..939f79e2 100644
--- a/device/bluetooth/test/mock_bluetooth_adapter.h
+++ b/device/bluetooth/test/mock_bluetooth_adapter.h
@@ -30,6 +30,10 @@
   class Observer : public BluetoothAdapter::Observer {
    public:
     Observer(scoped_refptr<BluetoothAdapter> adapter);
+
+    Observer(const Observer&) = delete;
+    Observer& operator=(const Observer&) = delete;
+
     ~Observer() override;
 
     MOCK_METHOD2(AdapterPresentChanged, void(BluetoothAdapter*, bool));
@@ -45,8 +49,6 @@
 
    private:
     const scoped_refptr<BluetoothAdapter> adapter_;
-
-    DISALLOW_COPY_AND_ASSIGN(Observer);
   };
 
   MockBluetoothAdapter();
diff --git a/device/bluetooth/test/mock_bluetooth_gatt_characteristic.h b/device/bluetooth/test/mock_bluetooth_gatt_characteristic.h
index 3ea4055..dbe2bf35 100644
--- a/device/bluetooth/test/mock_bluetooth_gatt_characteristic.h
+++ b/device/bluetooth/test/mock_bluetooth_gatt_characteristic.h
@@ -34,6 +34,12 @@
                                   const BluetoothUUID& uuid,
                                   Properties properties,
                                   Permissions permissions);
+
+  MockBluetoothGattCharacteristic(const MockBluetoothGattCharacteristic&) =
+      delete;
+  MockBluetoothGattCharacteristic& operator=(
+      const MockBluetoothGattCharacteristic&) = delete;
+
   ~MockBluetoothGattCharacteristic() override;
 
   MOCK_CONST_METHOD0(GetIdentifier, std::string());
@@ -139,9 +145,6 @@
                void(BluetoothRemoteGattDescriptor*,
                     base::OnceClosure&,
                     ErrorCallback&));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockBluetoothGattCharacteristic);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_gatt_descriptor.h b/device/bluetooth/test/mock_bluetooth_gatt_descriptor.h
index 06af5cb..12a7fc0 100644
--- a/device/bluetooth/test/mock_bluetooth_gatt_descriptor.h
+++ b/device/bluetooth/test/mock_bluetooth_gatt_descriptor.h
@@ -28,6 +28,11 @@
       const std::string& identifier,
       const BluetoothUUID& uuid,
       BluetoothRemoteGattCharacteristic::Permissions permissions);
+
+  MockBluetoothGattDescriptor(const MockBluetoothGattDescriptor&) = delete;
+  MockBluetoothGattDescriptor& operator=(const MockBluetoothGattDescriptor&) =
+      delete;
+
   ~MockBluetoothGattDescriptor() override;
 
   MOCK_CONST_METHOD0(GetIdentifier, std::string());
@@ -49,9 +54,6 @@
                void(const std::vector<uint8_t>&,
                     base::OnceClosure&,
                     ErrorCallback&));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockBluetoothGattDescriptor);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_gatt_notify_session.h b/device/bluetooth/test/mock_bluetooth_gatt_notify_session.h
index 1139bd1..aaa5c668 100644
--- a/device/bluetooth/test/mock_bluetooth_gatt_notify_session.h
+++ b/device/bluetooth/test/mock_bluetooth_gatt_notify_session.h
@@ -24,6 +24,12 @@
  public:
   explicit MockBluetoothGattNotifySession(
       base::WeakPtr<BluetoothRemoteGattCharacteristic> characteristic);
+
+  MockBluetoothGattNotifySession(const MockBluetoothGattNotifySession&) =
+      delete;
+  MockBluetoothGattNotifySession& operator=(
+      const MockBluetoothGattNotifySession&) = delete;
+
   ~MockBluetoothGattNotifySession() override;
 
   MOCK_METHOD0(IsActive, bool());
@@ -46,8 +52,6 @@
                 const std::vector<uint8_t>& value);
 
   base::RepeatingTimer test_notifications_timer_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockBluetoothGattNotifySession);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/mock_bluetooth_gatt_service.h b/device/bluetooth/test/mock_bluetooth_gatt_service.h
index 60c2d96..8cb9d673 100644
--- a/device/bluetooth/test/mock_bluetooth_gatt_service.h
+++ b/device/bluetooth/test/mock_bluetooth_gatt_service.h
@@ -26,6 +26,10 @@
                            const std::string& identifier,
                            const BluetoothUUID& uuid,
                            bool is_primary);
+
+  MockBluetoothGattService(const MockBluetoothGattService&) = delete;
+  MockBluetoothGattService& operator=(const MockBluetoothGattService&) = delete;
+
   ~MockBluetoothGattService() override;
 
   MOCK_CONST_METHOD0(GetIdentifier, std::string());
@@ -44,9 +48,6 @@
 
   void AddMockCharacteristic(
       std::unique_ptr<MockBluetoothGattCharacteristic> mock_characteristic);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockBluetoothGattService);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/test_bluetooth_adapter_observer.h b/device/bluetooth/test/test_bluetooth_adapter_observer.h
index 46721f1..99d96c0 100644
--- a/device/bluetooth/test/test_bluetooth_adapter_observer.h
+++ b/device/bluetooth/test/test_bluetooth_adapter_observer.h
@@ -20,6 +20,11 @@
  public:
   explicit TestBluetoothAdapterObserver(
       scoped_refptr<BluetoothAdapter> adapter);
+
+  TestBluetoothAdapterObserver(const TestBluetoothAdapterObserver&) = delete;
+  TestBluetoothAdapterObserver& operator=(const TestBluetoothAdapterObserver&) =
+      delete;
+
   ~TestBluetoothAdapterObserver() override;
 
   // Reset counters and cached values.
@@ -287,8 +292,6 @@
   std::string last_gatt_descriptor_id_;
   BluetoothUUID last_gatt_descriptor_uuid_;
   std::vector<uint8_t> last_changed_descriptor_value_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestBluetoothAdapterObserver);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/test_bluetooth_advertisement_observer.h b/device/bluetooth/test/test_bluetooth_advertisement_observer.h
index c123d2d..070cc5c 100644
--- a/device/bluetooth/test/test_bluetooth_advertisement_observer.h
+++ b/device/bluetooth/test/test_bluetooth_advertisement_observer.h
@@ -18,6 +18,12 @@
  public:
   explicit TestBluetoothAdvertisementObserver(
       scoped_refptr<BluetoothAdvertisement> advertisement);
+
+  TestBluetoothAdvertisementObserver(
+      const TestBluetoothAdvertisementObserver&) = delete;
+  TestBluetoothAdvertisementObserver& operator=(
+      const TestBluetoothAdvertisementObserver&) = delete;
+
   ~TestBluetoothAdvertisementObserver() override;
 
   // BluetoothAdvertisement::Observer:
@@ -30,8 +36,6 @@
   bool released_ = false;
   size_t released_count_ = 0;
   scoped_refptr<BluetoothAdvertisement> advertisement_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestBluetoothAdvertisementObserver);
 };
 
 }  // namespace device
diff --git a/device/bluetooth/test/test_bluetooth_local_gatt_service_delegate.h b/device/bluetooth/test/test_bluetooth_local_gatt_service_delegate.h
index 4be93a9c..6324721 100644
--- a/device/bluetooth/test/test_bluetooth_local_gatt_service_delegate.h
+++ b/device/bluetooth/test/test_bluetooth_local_gatt_service_delegate.h
@@ -20,6 +20,12 @@
     : public BluetoothLocalGattService::Delegate {
  public:
   TestBluetoothLocalGattServiceDelegate();
+
+  TestBluetoothLocalGattServiceDelegate(
+      const TestBluetoothLocalGattServiceDelegate&) = delete;
+  TestBluetoothLocalGattServiceDelegate& operator=(
+      const TestBluetoothLocalGattServiceDelegate&) = delete;
+
   virtual ~TestBluetoothLocalGattServiceDelegate();
 
   // BluetoothLocalGattService::Delegate overrides:
@@ -89,8 +95,6 @@
   BluetoothLocalGattDescriptor* expected_descriptor_;
 
   std::map<std::string, bool> notifications_started_for_characteristic_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestBluetoothLocalGattServiceDelegate);
 };
 
 }  // namespace device
diff --git a/device/fido/aoa/android_accessory_discovery.h b/device/fido/aoa/android_accessory_discovery.h
index cf22a43..5a795c4 100644
--- a/device/fido/aoa/android_accessory_discovery.h
+++ b/device/fido/aoa/android_accessory_discovery.h
@@ -55,6 +55,11 @@
   // device.
   AndroidAccessoryDiscovery(mojo::Remote<device::mojom::UsbDeviceManager>,
                             std::string request_description);
+
+  AndroidAccessoryDiscovery(const AndroidAccessoryDiscovery&) = delete;
+  AndroidAccessoryDiscovery& operator=(const AndroidAccessoryDiscovery&) =
+      delete;
+
   ~AndroidAccessoryDiscovery() override;
 
  private:
@@ -109,8 +114,6 @@
   mojo::AssociatedReceiver<device::mojom::UsbDeviceManagerClient> receiver_{
       this};
   base::WeakPtrFactory<AndroidAccessoryDiscovery> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(AndroidAccessoryDiscovery);
 };
 
 }  // namespace device
diff --git a/device/fido/attestation_object.h b/device/fido/attestation_object.h
index 259b089..84e82d3 100644
--- a/device/fido/attestation_object.h
+++ b/device/fido/attestation_object.h
@@ -32,6 +32,10 @@
                     std::unique_ptr<AttestationStatement> statement);
   AttestationObject(AttestationObject&& other);
   AttestationObject& operator=(AttestationObject&& other);
+
+  AttestationObject(const AttestationObject&) = delete;
+  AttestationObject& operator=(const AttestationObject&) = delete;
+
   ~AttestationObject();
 
   std::vector<uint8_t> GetCredentialId() const;
@@ -75,8 +79,6 @@
  private:
   AuthenticatorData authenticator_data_;
   std::unique_ptr<AttestationStatement> attestation_statement_;
-
-  DISALLOW_COPY_AND_ASSIGN(AttestationObject);
 };
 
 // Produces a WebAuthN style CBOR-encoded byte-array
diff --git a/device/fido/attestation_statement.h b/device/fido/attestation_statement.h
index c116bbad..ceb9f30 100644
--- a/device/fido/attestation_statement.h
+++ b/device/fido/attestation_statement.h
@@ -24,6 +24,9 @@
 // https://www.w3.org/TR/2017/WD-webauthn-20170505/#cred-attestation.
 class COMPONENT_EXPORT(DEVICE_FIDO) AttestationStatement {
  public:
+  AttestationStatement(const AttestationStatement&) = delete;
+  AttestationStatement& operator=(const AttestationStatement&) = delete;
+
   virtual ~AttestationStatement();
 
   // The CBOR map data to be added to the attestation object, structured
@@ -52,9 +55,6 @@
  protected:
   explicit AttestationStatement(std::string format);
   const std::string format_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AttestationStatement);
 };
 
 // NoneAttestationStatement represents a “none” attestation, which is used when
@@ -64,15 +64,16 @@
     : public AttestationStatement {
  public:
   NoneAttestationStatement();
+
+  NoneAttestationStatement(const NoneAttestationStatement&) = delete;
+  NoneAttestationStatement& operator=(const NoneAttestationStatement&) = delete;
+
   ~NoneAttestationStatement() override;
 
   cbor::Value AsCBOR() const override;
   bool IsSelfAttestation() const override;
   bool IsAttestationCertificateInappropriatelyIdentifying() const override;
   absl::optional<base::span<const uint8_t>> GetLeafCertificate() const override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(NoneAttestationStatement);
 };
 
 COMPONENT_EXPORT(DEVICE_FIDO)
diff --git a/device/fido/attestation_statement_formats.h b/device/fido/attestation_statement_formats.h
index 3a80cd72..fa8c78c 100644
--- a/device/fido/attestation_statement_formats.h
+++ b/device/fido/attestation_statement_formats.h
@@ -27,6 +27,10 @@
 
   FidoAttestationStatement(std::vector<uint8_t> signature,
                            std::vector<std::vector<uint8_t>> x509_certificates);
+
+  FidoAttestationStatement(const FidoAttestationStatement&) = delete;
+  FidoAttestationStatement& operator=(const FidoAttestationStatement&) = delete;
+
   ~FidoAttestationStatement() override;
 
   cbor::Value AsCBOR() const override;
@@ -37,8 +41,6 @@
  private:
   const std::vector<uint8_t> signature_;
   const std::vector<std::vector<uint8_t>> x509_certificates_;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoAttestationStatement);
 };
 
 // Implements the "packed" attestation statement format from
diff --git a/device/fido/attested_credential_data.h b/device/fido/attested_credential_data.h
index 6302880..c38ee13 100644
--- a/device/fido/attested_credential_data.h
+++ b/device/fido/attested_credential_data.h
@@ -42,6 +42,9 @@
       std::vector<uint8_t> credential_id,
       std::unique_ptr<PublicKey> public_key);
 
+  AttestedCredentialData(const AttestedCredentialData&) = delete;
+  AttestedCredentialData& operator=(const AttestedCredentialData&) = delete;
+
   ~AttestedCredentialData();
 
   AttestedCredentialData& operator=(AttestedCredentialData&& other);
@@ -73,8 +76,6 @@
 
   std::vector<uint8_t> credential_id_;
   std::unique_ptr<PublicKey> public_key_;
-
-  DISALLOW_COPY_AND_ASSIGN(AttestedCredentialData);
 };
 
 }  // namespace device
diff --git a/device/fido/authenticator_data.h b/device/fido/authenticator_data.h
index e9d18911..44092850 100644
--- a/device/fido/authenticator_data.h
+++ b/device/fido/authenticator_data.h
@@ -57,6 +57,9 @@
   AuthenticatorData(AuthenticatorData&& other);
   AuthenticatorData& operator=(AuthenticatorData&& other);
 
+  AuthenticatorData(const AuthenticatorData&) = delete;
+  AuthenticatorData& operator=(const AuthenticatorData&) = delete;
+
   ~AuthenticatorData();
 
   // Replaces device AAGUID in attested credential data section with zeros.
@@ -124,8 +127,6 @@
   absl::optional<AttestedCredentialData> attested_data_;
   // If |extensions_| has a value, then it will be a CBOR map.
   absl::optional<cbor::Value> extensions_;
-
-  DISALLOW_COPY_AND_ASSIGN(AuthenticatorData);
 };
 
 }  // namespace device
diff --git a/device/fido/authenticator_get_info_response.h b/device/fido/authenticator_get_info_response.h
index 82d5761..36aa15d5 100644
--- a/device/fido/authenticator_get_info_response.h
+++ b/device/fido/authenticator_get_info_response.h
@@ -31,6 +31,11 @@
                                base::span<const uint8_t, kAaguidLength> aaguid);
   AuthenticatorGetInfoResponse(AuthenticatorGetInfoResponse&& that);
   AuthenticatorGetInfoResponse& operator=(AuthenticatorGetInfoResponse&& other);
+
+  AuthenticatorGetInfoResponse(const AuthenticatorGetInfoResponse&) = delete;
+  AuthenticatorGetInfoResponse& operator=(const AuthenticatorGetInfoResponse&) =
+      delete;
+
   ~AuthenticatorGetInfoResponse();
 
   static std::vector<uint8_t> EncodeToCBOR(
@@ -60,9 +65,6 @@
   absl::optional<uint32_t> max_cred_blob_length;
 
   AuthenticatorSupportedOptions options;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(AuthenticatorGetInfoResponse);
 };
 
 }  // namespace device
diff --git a/device/fido/authenticator_make_credential_response.h b/device/fido/authenticator_make_credential_response.h
index d046cd7..e3e92be 100644
--- a/device/fido/authenticator_make_credential_response.h
+++ b/device/fido/authenticator_make_credential_response.h
@@ -39,6 +39,12 @@
       AuthenticatorMakeCredentialResponse&& that);
   AuthenticatorMakeCredentialResponse& operator=(
       AuthenticatorMakeCredentialResponse&& other);
+
+  AuthenticatorMakeCredentialResponse(
+      const AuthenticatorMakeCredentialResponse&) = delete;
+  AuthenticatorMakeCredentialResponse& operator=(
+      const AuthenticatorMakeCredentialResponse&) = delete;
+
   ~AuthenticatorMakeCredentialResponse();
 
   std::vector<uint8_t> GetCBOREncodedAttestationObject() const;
@@ -102,8 +108,6 @@
   // returned if the credential is created with the largeBlobKey extension on a
   // capable authenticator.
   absl::optional<std::array<uint8_t, kLargeBlobKeyLength>> large_blob_key_;
-
-  DISALLOW_COPY_AND_ASSIGN(AuthenticatorMakeCredentialResponse);
 };
 
 // Through cbor::Writer, produces a CTAP style CBOR-encoded byte array
diff --git a/device/fido/ble_adapter_manager.h b/device/fido/ble_adapter_manager.h
index a468b32..f4e247e 100644
--- a/device/fido/ble_adapter_manager.h
+++ b/device/fido/ble_adapter_manager.h
@@ -24,6 +24,10 @@
   //   a) Exposing API to trigger power Bluetooth adapter on/off.
   //   b) Notifying FidoRequestHandler when Bluetooth adapter power changes.
   explicit BleAdapterManager(FidoRequestHandlerBase* request_handler);
+
+  BleAdapterManager(const BleAdapterManager&) = delete;
+  BleAdapterManager& operator=(const BleAdapterManager&) = delete;
+
   ~BleAdapterManager() override;
 
   void SetAdapterPower(bool set_power_on);
@@ -41,8 +45,6 @@
   bool adapter_powered_on_programmatically_ = false;
 
   base::WeakPtrFactory<BleAdapterManager> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(BleAdapterManager);
 };
 
 }  // namespace device
diff --git a/device/fido/ble_adapter_manager_unittest.cc b/device/fido/ble_adapter_manager_unittest.cc
index c90bf48..5ae690d 100644
--- a/device/fido/ble_adapter_manager_unittest.cc
+++ b/device/fido/ble_adapter_manager_unittest.cc
@@ -36,6 +36,10 @@
 class MockObserver : public FidoRequestHandlerBase::Observer {
  public:
   MockObserver() = default;
+
+  MockObserver(const MockObserver&) = delete;
+  MockObserver& operator=(const MockObserver&) = delete;
+
   ~MockObserver() override = default;
 
   MOCK_METHOD1(OnTransportAvailabilityEnumerated,
@@ -57,9 +61,6 @@
   MOCK_METHOD1(OnRetryUserVerification, void(int));
   MOCK_METHOD0(OnInternalUserVerificationLocked, void());
   MOCK_METHOD1(SetMightCreateResidentCredential, void(bool));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockObserver);
 };
 
 class FakeFidoRequestHandlerBase : public FidoRequestHandlerBase {
diff --git a/device/fido/cable/fido_ble_connection.h b/device/fido/cable/fido_ble_connection.h
index f1d7d6fd..f0f2f53c 100644
--- a/device/fido/cable/fido_ble_connection.h
+++ b/device/fido/cable/fido_ble_connection.h
@@ -57,6 +57,10 @@
                     std::string device_address,
                     BluetoothUUID service_uuid,
                     ReadCallback read_callback);
+
+  FidoBleConnection(const FidoBleConnection&) = delete;
+  FidoBleConnection& operator=(const FidoBleConnection&) = delete;
+
   ~FidoBleConnection() override;
 
   const std::string& address() const { return address_; }
@@ -123,8 +127,6 @@
   absl::optional<std::string> service_revision_bitfield_id_;
 
   base::WeakPtrFactory<FidoBleConnection> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoBleConnection);
 };
 
 }  // namespace device
diff --git a/device/fido/cable/fido_ble_frames.h b/device/fido/cable/fido_ble_frames.h
index a0ea3817..d3ba70d 100644
--- a/device/fido/cable/fido_ble_frames.h
+++ b/device/fido/cable/fido_ble_frames.h
@@ -168,6 +168,10 @@
  public:
   explicit FidoBleFrameAssembler(
       const FidoBleFrameInitializationFragment& fragment);
+
+  FidoBleFrameAssembler(const FidoBleFrameAssembler&) = delete;
+  FidoBleFrameAssembler& operator=(const FidoBleFrameAssembler&) = delete;
+
   ~FidoBleFrameAssembler();
 
   bool IsDone() const;
@@ -179,8 +183,6 @@
   uint16_t data_length_ = 0;
   uint8_t sequence_number_ = 0;
   FidoBleFrame frame_;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoBleFrameAssembler);
 };
 
 }  // namespace device
diff --git a/device/fido/cable/fido_ble_transaction.h b/device/fido/cable/fido_ble_transaction.h
index ae3eae6b..0fe9a976 100644
--- a/device/fido/cable/fido_ble_transaction.h
+++ b/device/fido/cable/fido_ble_transaction.h
@@ -29,6 +29,10 @@
 
   FidoBleTransaction(FidoBleConnection* connection,
                      uint16_t control_point_length);
+
+  FidoBleTransaction(const FidoBleTransaction&) = delete;
+  FidoBleTransaction& operator=(const FidoBleTransaction&) = delete;
+
   ~FidoBleTransaction();
 
   void WriteRequestFrame(FidoBleFrame request_frame, FrameCallback callback);
@@ -66,8 +70,6 @@
   bool cancel_sent_ = false;
 
   base::WeakPtrFactory<FidoBleTransaction> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoBleTransaction);
 };
 
 }  // namespace device
diff --git a/device/fido/cable/fido_cable_device.h b/device/fido/cable/fido_cable_device.h
index 064548b..3964723 100644
--- a/device/fido/cable/fido_cable_device.h
+++ b/device/fido/cable/fido_cable_device.h
@@ -39,6 +39,10 @@
   FidoCableDevice(BluetoothAdapter* adapter, std::string address);
   // Constructor used for testing purposes.
   FidoCableDevice(std::unique_ptr<FidoBleConnection> connection);
+
+  FidoCableDevice(const FidoCableDevice&) = delete;
+  FidoCableDevice& operator=(const FidoCableDevice&) = delete;
+
   ~FidoCableDevice() override;
 
   // Returns FidoDevice::GetId() for a given FidoBleConnection address.
@@ -137,8 +141,6 @@
 
   absl::optional<EncryptionData> encryption_data_;
   base::WeakPtrFactory<FidoCableDevice> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoCableDevice);
 };
 
 }  // namespace device
diff --git a/device/fido/cable/fido_cable_discovery.h b/device/fido/cable/fido_cable_discovery.h
index a73b2c6..3ca1c75 100644
--- a/device/fido/cable/fido_cable_discovery.h
+++ b/device/fido/cable/fido_cable_discovery.h
@@ -36,6 +36,10 @@
       public FidoCableDevice::Observer {
  public:
   explicit FidoCableDiscovery(std::vector<CableDiscoveryData> discovery_data);
+
+  FidoCableDiscovery(const FidoCableDiscovery&) = delete;
+  FidoCableDiscovery& operator=(const FidoCableDiscovery&) = delete;
+
   ~FidoCableDiscovery() override;
 
   // FidoDeviceDiscovery:
@@ -178,8 +182,6 @@
   base::flat_set<CableV1DiscoveryEvent> recorded_events_;
 
   base::WeakPtrFactory<FidoCableDiscovery> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoCableDiscovery);
 };
 
 }  // namespace device
diff --git a/device/fido/cable/fido_cable_handshake_handler.h b/device/fido/cable/fido_cable_handshake_handler.h
index f1ce823..ed634b5 100644
--- a/device/fido/cable/fido_cable_handshake_handler.h
+++ b/device/fido/cable/fido_cable_handshake_handler.h
@@ -47,6 +47,11 @@
   FidoCableV1HandshakeHandler(FidoCableDevice* device,
                               base::span<const uint8_t, 8> nonce,
                               base::span<const uint8_t, 32> session_pre_key);
+
+  FidoCableV1HandshakeHandler(const FidoCableV1HandshakeHandler&) = delete;
+  FidoCableV1HandshakeHandler& operator=(const FidoCableV1HandshakeHandler&) =
+      delete;
+
   ~FidoCableV1HandshakeHandler() override;
 
   // FidoCableHandshakeHandler:
@@ -69,8 +74,6 @@
   std::string handshake_key_;
 
   base::WeakPtrFactory<FidoCableV1HandshakeHandler> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoCableV1HandshakeHandler);
 };
 
 }  // namespace device
diff --git a/device/fido/cable/fido_tunnel_device.h b/device/fido/cable/fido_tunnel_device.h
index 0b46acc..a6ed23e 100644
--- a/device/fido/cable/fido_tunnel_device.h
+++ b/device/fido/cable/fido_tunnel_device.h
@@ -48,6 +48,9 @@
                    std::unique_ptr<Pairing> pairing,
                    base::OnceClosure pairing_is_invalid);
 
+  FidoTunnelDevice(const FidoTunnelDevice&) = delete;
+  FidoTunnelDevice& operator=(const FidoTunnelDevice&) = delete;
+
   ~FidoTunnelDevice() override;
 
   // MatchAdvert is only valid for a pairing-initiated connection. It returns
@@ -164,8 +167,6 @@
   DeviceCallback callback_;
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<FidoTunnelDevice> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoTunnelDevice);
 };
 
 }  // namespace cablev2
diff --git a/device/fido/cable/mock_fido_ble_connection.h b/device/fido/cable/mock_fido_ble_connection.h
index ae802c35..d108bff 100644
--- a/device/fido/cable/mock_fido_ble_connection.h
+++ b/device/fido/cable/mock_fido_ble_connection.h
@@ -20,6 +20,10 @@
 class MockFidoBleConnection : public FidoBleConnection {
  public:
   MockFidoBleConnection(BluetoothAdapter* adapter, std::string device_address);
+
+  MockFidoBleConnection(const MockFidoBleConnection&) = delete;
+  MockFidoBleConnection& operator=(const MockFidoBleConnection&) = delete;
+
   ~MockFidoBleConnection() override;
 
   // GMock cannot mock a method taking a move-only type.
@@ -36,9 +40,6 @@
                          WriteCallback cb) override;
 
   ReadCallback& read_callback() { return read_callback_; }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockFidoBleConnection);
 };
 
 }  // namespace device
diff --git a/device/fido/credential_management_handler.h b/device/fido/credential_management_handler.h
index c7e4dfd..31f54f0 100644
--- a/device/fido/credential_management_handler.h
+++ b/device/fido/credential_management_handler.h
@@ -62,6 +62,11 @@
       ReadyCallback ready_callback,
       GetPINCallback get_pin_callback,
       FinishedCallback finished_callback);
+
+  CredentialManagementHandler(const CredentialManagementHandler&) = delete;
+  CredentialManagementHandler& operator=(const CredentialManagementHandler&) =
+      delete;
+
   ~CredentialManagementHandler() override;
 
   // GetCredentials invokes a series of commands to fetch all credentials stored
@@ -137,8 +142,6 @@
   FinishedCallback finished_callback_;
 
   base::WeakPtrFactory<CredentialManagementHandler> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(CredentialManagementHandler);
 };
 
 }  // namespace device
diff --git a/device/fido/ctap2_device_operation.h b/device/fido/ctap2_device_operation.h
index 779dc2f4..cbca1ad8 100644
--- a/device/fido/ctap2_device_operation.h
+++ b/device/fido/ctap2_device_operation.h
@@ -71,6 +71,9 @@
         device_response_parser_(std::move(device_response_parser)),
         string_fixup_predicate_(string_fixup_predicate) {}
 
+  Ctap2DeviceOperation(const Ctap2DeviceOperation&) = delete;
+  Ctap2DeviceOperation& operator=(const Ctap2DeviceOperation&) = delete;
+
   ~Ctap2DeviceOperation() override = default;
 
   void Start() override {
@@ -205,8 +208,6 @@
   DeviceResponseParser device_response_parser_;
   const CBORPathPredicate string_fixup_predicate_;
   base::WeakPtrFactory<Ctap2DeviceOperation> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(Ctap2DeviceOperation);
 };
 
 }  // namespace device
diff --git a/device/fido/device_operation.h b/device/fido/device_operation.h
index c42bec4..c9b31bd 100644
--- a/device/fido/device_operation.h
+++ b/device/fido/device_operation.h
@@ -48,6 +48,9 @@
         request_(std::move(request)),
         callback_(std::move(callback)) {}
 
+  DeviceOperation(const DeviceOperation&) = delete;
+  DeviceOperation& operator=(const DeviceOperation&) = delete;
+
   ~DeviceOperation() override = default;
 
  protected:
@@ -71,8 +74,6 @@
   FidoDevice* const device_ = nullptr;
   Request request_;
   DeviceResponseCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeviceOperation);
 };
 
 }  // namespace device
diff --git a/device/fido/fake_fido_discovery.h b/device/fido/fake_fido_discovery.h
index ee5aa1f..236a56c 100644
--- a/device/fido/fake_fido_discovery.h
+++ b/device/fido/fake_fido_discovery.h
@@ -95,6 +95,10 @@
   using StartMode = FakeFidoDiscovery::StartMode;
 
   FakeFidoDiscoveryFactory();
+
+  FakeFidoDiscoveryFactory(const FakeFidoDiscoveryFactory&) = delete;
+  FakeFidoDiscoveryFactory& operator=(const FakeFidoDiscoveryFactory&) = delete;
+
   ~FakeFidoDiscoveryFactory() override;
 
   // Constructs a fake discovery to be returned from the next call to
@@ -119,8 +123,6 @@
   std::unique_ptr<FakeFidoDiscovery> next_nfc_discovery_;
   std::unique_ptr<FakeFidoDiscovery> next_cable_discovery_;
   std::unique_ptr<FakeFidoDiscovery> next_platform_discovery_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeFidoDiscoveryFactory);
 };
 
 }  // namespace test
diff --git a/device/fido/fake_fido_discovery_unittest.cc b/device/fido/fake_fido_discovery_unittest.cc
index cc29172..dd5b20c 100644
--- a/device/fido/fake_fido_discovery_unittest.cc
+++ b/device/fido/fake_fido_discovery_unittest.cc
@@ -26,14 +26,15 @@
 class FakeFidoDiscoveryTest : public ::testing::Test {
  public:
   FakeFidoDiscoveryTest() = default;
+
+  FakeFidoDiscoveryTest(const FakeFidoDiscoveryTest&) = delete;
+  FakeFidoDiscoveryTest& operator=(const FakeFidoDiscoveryTest&) = delete;
+
   ~FakeFidoDiscoveryTest() override = default;
 
  protected:
   FakeFidoDiscoveryFactory fake_fido_discovery_factory_;
   base::test::TaskEnvironment task_environment_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FakeFidoDiscoveryTest);
 };
 
 using FakeFidoDiscoveryFactoryTest = FakeFidoDiscoveryTest;
diff --git a/device/fido/fido_authenticator.h b/device/fido/fido_authenticator.h
index 8f7fffb..0a45824 100644
--- a/device/fido/fido_authenticator.h
+++ b/device/fido/fido_authenticator.h
@@ -81,6 +81,10 @@
           callback)>;
 
   FidoAuthenticator() = default;
+
+  FidoAuthenticator(const FidoAuthenticator&) = delete;
+  FidoAuthenticator& operator=(const FidoAuthenticator&) = delete;
+
   virtual ~FidoAuthenticator() = default;
 
   // Sends GetInfo request to connected authenticator. Once response to GetInfo
@@ -283,9 +287,6 @@
   virtual bool IsChromeOSAuthenticator() const = 0;
 #endif
   virtual base::WeakPtr<FidoAuthenticator> GetWeakPtr() = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(FidoAuthenticator);
 };
 
 }  // namespace device
diff --git a/device/fido/fido_device.h b/device/fido/fido_device.h
index e2ccf3bf..36d1991c 100644
--- a/device/fido/fido_device.h
+++ b/device/fido/fido_device.h
@@ -59,6 +59,10 @@
   };
 
   FidoDevice();
+
+  FidoDevice(const FidoDevice&) = delete;
+  FidoDevice& operator=(const FidoDevice&) = delete;
+
   virtual ~FidoDevice();
   // Pure virtual function defined by each device type, implementing
   // the device communication transaction. The function must not immediately
@@ -147,8 +151,6 @@
   // device. It starts at one so that zero can be used as an invalid value where
   // needed.
   CancelToken next_cancel_token_ = kInvalidCancelToken + 1;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoDevice);
 };
 
 }  // namespace device
diff --git a/device/fido/fido_device_authenticator.h b/device/fido/fido_device_authenticator.h
index a90c519..aeebe55b 100644
--- a/device/fido/fido_device_authenticator.h
+++ b/device/fido/fido_device_authenticator.h
@@ -38,6 +38,10 @@
     : public FidoAuthenticator {
  public:
   explicit FidoDeviceAuthenticator(std::unique_ptr<FidoDevice> device);
+
+  FidoDeviceAuthenticator(const FidoDeviceAuthenticator&) = delete;
+  FidoDeviceAuthenticator& operator=(const FidoDeviceAuthenticator&) = delete;
+
   ~FidoDeviceAuthenticator() override;
 
   // FidoAuthenticator:
@@ -268,8 +272,6 @@
   absl::optional<PINUVAuthProtocol> chosen_pin_uv_auth_protocol_;
 
   base::WeakPtrFactory<FidoDeviceAuthenticator> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoDeviceAuthenticator);
 };
 
 }  // namespace device
diff --git a/device/fido/fido_device_discovery_unittest.cc b/device/fido/fido_device_discovery_unittest.cc
index 6b1dd0e..37445da 100644
--- a/device/fido/fido_device_discovery_unittest.cc
+++ b/device/fido/fido_device_discovery_unittest.cc
@@ -32,6 +32,10 @@
  public:
   explicit ConcreteFidoDiscovery(FidoTransportProtocol transport)
       : FidoDeviceDiscovery(transport) {}
+
+  ConcreteFidoDiscovery(const ConcreteFidoDiscovery&) = delete;
+  ConcreteFidoDiscovery& operator=(const ConcreteFidoDiscovery&) = delete;
+
   ~ConcreteFidoDiscovery() override = default;
 
   MOCK_METHOD0(StartInternal, void());
@@ -39,9 +43,6 @@
   using FidoDeviceDiscovery::AddDevice;
   using FidoDeviceDiscovery::NotifyDiscoveryStarted;
   using FidoDeviceDiscovery::RemoveDevice;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ConcreteFidoDiscovery);
 };
 
 }  // namespace
diff --git a/device/fido/fido_discovery_base.h b/device/fido/fido_discovery_base.h
index 8a29e3a..2c8d9aa 100644
--- a/device/fido/fido_discovery_base.h
+++ b/device/fido/fido_discovery_base.h
@@ -20,6 +20,9 @@
 
 class COMPONENT_EXPORT(DEVICE_FIDO) FidoDiscoveryBase {
  public:
+  FidoDiscoveryBase(const FidoDiscoveryBase&) = delete;
+  FidoDiscoveryBase& operator=(const FidoDiscoveryBase&) = delete;
+
   virtual ~FidoDiscoveryBase();
 
   class COMPONENT_EXPORT(DEVICE_FIDO) Observer {
@@ -62,8 +65,6 @@
  private:
   const FidoTransportProtocol transport_;
   Observer* observer_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoDiscoveryBase);
 };
 
 }  // namespace device
diff --git a/device/fido/fido_request_handler_base.h b/device/fido/fido_request_handler_base.h
index 862d9a4..fa1533d 100644
--- a/device/fido/fido_request_handler_base.h
+++ b/device/fido/fido_request_handler_base.h
@@ -196,6 +196,10 @@
   FidoRequestHandlerBase(
       FidoDiscoveryFactory* fido_discovery_factory,
       const base::flat_set<FidoTransportProtocol>& available_transports);
+
+  FidoRequestHandlerBase(const FidoRequestHandlerBase&) = delete;
+  FidoRequestHandlerBase& operator=(const FidoRequestHandlerBase&) = delete;
+
   ~FidoRequestHandlerBase() override;
 
   // Triggers DispatchRequest() if |active_authenticators_| hold
@@ -327,7 +331,6 @@
   bool internal_authenticator_found_ = false;
 
   base::WeakPtrFactory<FidoRequestHandlerBase> weak_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(FidoRequestHandlerBase);
 };
 
 }  // namespace device
diff --git a/device/fido/fido_request_handler_unittest.cc b/device/fido/fido_request_handler_unittest.cc
index b959aaf..1f26312 100644
--- a/device/fido/fido_request_handler_unittest.cc
+++ b/device/fido/fido_request_handler_unittest.cc
@@ -72,6 +72,10 @@
       FidoRequestHandlerBase::TransportAvailabilityInfo>;
 
   TestObserver() = default;
+
+  TestObserver(const TestObserver&) = delete;
+  TestObserver& operator=(const TestObserver&) = delete;
+
   ~TestObserver() override = default;
 
   FidoRequestHandlerBase::TransportAvailabilityInfo
@@ -126,8 +130,6 @@
  private:
   TransportAvailabilityNotificationReceiver
       transport_availability_notification_receiver_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestObserver);
 };
 
 // Fake FidoTask implementation that sends an empty byte array to the device
diff --git a/device/fido/fido_task.h b/device/fido/fido_task.h
index acf467c69..313caab 100644
--- a/device/fido/fido_task.h
+++ b/device/fido/fido_task.h
@@ -23,6 +23,10 @@
  public:
   // The |device| must outlive the FidoTask instance.
   explicit FidoTask(FidoDevice* device);
+
+  FidoTask(const FidoTask&) = delete;
+  FidoTask& operator=(const FidoTask&) = delete;
+
   virtual ~FidoTask();
 
   // Cancel attempts to cancel the operation. This may safely be called at any
@@ -44,8 +48,6 @@
  private:
   FidoDevice* const device_;
   base::WeakPtrFactory<FidoTask> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoTask);
 };
 
 }  // namespace device
diff --git a/device/fido/get_assertion_request_handler.h b/device/fido/get_assertion_request_handler.h
index 3eb8a8f..37dcbcb 100644
--- a/device/fido/get_assertion_request_handler.h
+++ b/device/fido/get_assertion_request_handler.h
@@ -67,6 +67,11 @@
       CtapGetAssertionOptions request_options,
       bool allow_skipping_pin_touch,
       CompletionCallback completion_callback);
+
+  GetAssertionRequestHandler(const GetAssertionRequestHandler&) = delete;
+  GetAssertionRequestHandler& operator=(const GetAssertionRequestHandler&) =
+      delete;
+
   ~GetAssertionRequestHandler() override;
 
  private:
@@ -163,8 +168,6 @@
 
   SEQUENCE_CHECKER(my_sequence_checker_);
   base::WeakPtrFactory<GetAssertionRequestHandler> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(GetAssertionRequestHandler);
 };
 
 }  // namespace device
diff --git a/device/fido/get_assertion_task.h b/device/fido/get_assertion_task.h
index 7ec054c..25a64a4 100644
--- a/device/fido/get_assertion_task.h
+++ b/device/fido/get_assertion_task.h
@@ -48,6 +48,10 @@
                    CtapGetAssertionRequest request,
                    CtapGetAssertionOptions options,
                    GetAssertionTaskCallback callback);
+
+  GetAssertionTask(const GetAssertionTask&) = delete;
+  GetAssertionTask& operator=(const GetAssertionTask&) = delete;
+
   ~GetAssertionTask() override;
 
   // FidoTask:
@@ -107,8 +111,6 @@
   bool canceled_ = false;
 
   base::WeakPtrFactory<GetAssertionTask> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(GetAssertionTask);
 };
 
 }  // namespace device
diff --git a/device/fido/hid/fido_hid_device_unittest.cc b/device/fido/hid/fido_hid_device_unittest.cc
index 067a7de..866a1db 100644
--- a/device/fido/hid/fido_hid_device_unittest.cc
+++ b/device/fido/hid/fido_hid_device_unittest.cc
@@ -202,6 +202,12 @@
   explicit FidoDeviceEnumerateCallbackReceiver(
       device::mojom::HidManager* hid_manager)
       : hid_manager_(hid_manager) {}
+
+  FidoDeviceEnumerateCallbackReceiver(
+      const FidoDeviceEnumerateCallbackReceiver&) = delete;
+  FidoDeviceEnumerateCallbackReceiver& operator=(
+      const FidoDeviceEnumerateCallbackReceiver&) = delete;
+
   ~FidoDeviceEnumerateCallbackReceiver() = default;
 
   std::vector<std::unique_ptr<FidoHidDevice>> TakeReturnedDevicesFiltered() {
@@ -228,8 +234,6 @@
 
  private:
   device::mojom::HidManager* hid_manager_;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoDeviceEnumerateCallbackReceiver);
 };
 
 using TestDeviceCallbackReceiver =
diff --git a/device/fido/hid/fido_hid_discovery.h b/device/fido/hid/fido_hid_discovery.h
index b208c36..a25ceca 100644
--- a/device/fido/hid/fido_hid_discovery.h
+++ b/device/fido/hid/fido_hid_discovery.h
@@ -38,6 +38,10 @@
       device::mojom::HidManagerClient {
  public:
   explicit FidoHidDiscovery(base::flat_set<VidPid> ignore_list = {});
+
+  FidoHidDiscovery(const FidoHidDiscovery&) = delete;
+  FidoHidDiscovery& operator=(const FidoHidDiscovery&) = delete;
+
   ~FidoHidDiscovery() override;
 
   // Sets a callback for this class to use when binding a HidManager receiver.
@@ -61,8 +65,6 @@
   HidDeviceFilter filter_;
   base::flat_set<VidPid> ignore_list_;
   base::WeakPtrFactory<FidoHidDiscovery> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(FidoHidDiscovery);
 };
 
 }  // namespace device
diff --git a/device/fido/hid/fido_hid_message.h b/device/fido/hid/fido_hid_message.h
index affc9a8..33623515 100644
--- a/device/fido/hid/fido_hid_message.h
+++ b/device/fido/hid/fido_hid_message.h
@@ -39,6 +39,10 @@
 
   FidoHidMessage(FidoHidMessage&& that);
   FidoHidMessage& operator=(FidoHidMessage&& other);
+
+  FidoHidMessage(const FidoHidMessage&) = delete;
+  FidoHidMessage& operator=(const FidoHidMessage&) = delete;
+
   ~FidoHidMessage();
 
   bool MessageComplete() const;
@@ -68,8 +72,6 @@
   FidoHidDeviceCommand cmd_ = FidoHidDeviceCommand::kMsg;
   base::circular_deque<std::unique_ptr<FidoHidPacket>> packets_;
   size_t remaining_size_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoHidMessage);
 };
 
 }  // namespace device
diff --git a/device/fido/hid/fido_hid_packet.h b/device/fido/hid/fido_hid_packet.h
index a235763..3abf7feee 100644
--- a/device/fido/hid/fido_hid_packet.h
+++ b/device/fido/hid/fido_hid_packet.h
@@ -27,6 +27,10 @@
 class COMPONENT_EXPORT(DEVICE_FIDO) FidoHidPacket {
  public:
   FidoHidPacket(std::vector<uint8_t> data, uint32_t channel_id);
+
+  FidoHidPacket(const FidoHidPacket&) = delete;
+  FidoHidPacket& operator=(const FidoHidPacket&) = delete;
+
   virtual ~FidoHidPacket();
 
   virtual std::vector<uint8_t> GetSerializedData() const = 0;
@@ -41,8 +45,6 @@
 
  private:
   friend class HidMessage;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoHidPacket);
 };
 
 // FidoHidInitPacket, based on the CTAP specification consists of a header with
@@ -66,6 +68,10 @@
                     FidoHidDeviceCommand cmd,
                     std::vector<uint8_t> data,
                     uint16_t payload_length);
+
+  FidoHidInitPacket(const FidoHidInitPacket&) = delete;
+  FidoHidInitPacket& operator=(const FidoHidInitPacket&) = delete;
+
   ~FidoHidInitPacket() final;
 
   std::vector<uint8_t> GetSerializedData() const final;
@@ -75,8 +81,6 @@
  private:
   FidoHidDeviceCommand command_;
   uint16_t payload_length_;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoHidInitPacket);
 };
 
 // FidoHidContinuationPacket, based on the CTAP Specification consists of a
@@ -98,6 +102,11 @@
   FidoHidContinuationPacket(uint32_t channel_id,
                             uint8_t sequence,
                             std::vector<uint8_t> data);
+
+  FidoHidContinuationPacket(const FidoHidContinuationPacket&) = delete;
+  FidoHidContinuationPacket& operator=(const FidoHidContinuationPacket&) =
+      delete;
+
   ~FidoHidContinuationPacket() final;
 
   std::vector<uint8_t> GetSerializedData() const final;
@@ -105,8 +114,6 @@
 
  private:
   uint8_t sequence_;
-
-  DISALLOW_COPY_AND_ASSIGN(FidoHidContinuationPacket);
 };
 
 }  // namespace device
diff --git a/device/fido/mac/authenticator.h b/device/fido/mac/authenticator.h
index 67445ff..3189823c 100644
--- a/device/fido/mac/authenticator.h
+++ b/device/fido/mac/authenticator.h
@@ -47,6 +47,9 @@
   static std::unique_ptr<TouchIdAuthenticator> Create(
       AuthenticatorConfig config);
 
+  TouchIdAuthenticator(const TouchIdAuthenticator&) = delete;
+  TouchIdAuthenticator& operator=(const TouchIdAuthenticator&) = delete;
+
   ~TouchIdAuthenticator() override;
 
   bool HasCredentialForGetAssertionRequest(
@@ -85,9 +88,6 @@
   std::unique_ptr<Operation> operation_;
 
   base::WeakPtrFactory<TouchIdAuthenticator> weak_factory_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TouchIdAuthenticator);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/credential_store.h b/device/fido/mac/credential_store.h
index 644cf5f..2384a08 100644
--- a/device/fido/mac/credential_store.h
+++ b/device/fido/mac/credential_store.h
@@ -54,6 +54,10 @@
     : public ::device::fido::PlatformCredentialStore {
  public:
   explicit TouchIdCredentialStore(AuthenticatorConfig config);
+
+  TouchIdCredentialStore(const TouchIdCredentialStore&) = delete;
+  TouchIdCredentialStore& operator=(const TouchIdCredentialStore&) = delete;
+
   ~TouchIdCredentialStore() override;
 
   // An LAContext that has been successfully evaluated using |TouchIdContext|
@@ -137,8 +141,6 @@
 
   AuthenticatorConfig config_;
   LAContext* authentication_context_ = nullptr;
-
-  DISALLOW_COPY_AND_ASSIGN(TouchIdCredentialStore);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/fake_keychain.h b/device/fido/mac/fake_keychain.h
index 97f275aa..5484f6a 100644
--- a/device/fido/mac/fake_keychain.h
+++ b/device/fido/mac/fake_keychain.h
@@ -22,18 +22,23 @@
     Item();
     Item(Item&&);
     Item& operator=(Item&&);
+
+    Item(const Item&) = delete;
+    Item& operator=(const Item&) = delete;
+
     ~Item();
 
     std::string label;
     std::string application_label;
     std::string application_tag;
     base::ScopedCFTypeRef<SecKeyRef> private_key;
-
-   private:
-    DISALLOW_COPY_AND_ASSIGN(Item);
   };
 
   FakeKeychain();
+
+  FakeKeychain(const FakeKeychain&) = delete;
+  FakeKeychain& operator=(const FakeKeychain&) = delete;
+
   ~FakeKeychain() override;
 
  protected:
@@ -46,8 +51,6 @@
 
  private:
   std::vector<Item> items_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeKeychain);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/fake_touch_id_context.h b/device/fido/mac/fake_touch_id_context.h
index 5d75db8..b913c9cd 100644
--- a/device/fido/mac/fake_touch_id_context.h
+++ b/device/fido/mac/fake_touch_id_context.h
@@ -16,6 +16,9 @@
 class API_AVAILABLE(macosx(10.12.2)) FakeTouchIdContext
     : public TouchIdContext {
  public:
+  FakeTouchIdContext(const FakeTouchIdContext&) = delete;
+  FakeTouchIdContext& operator=(const FakeTouchIdContext&) = delete;
+
   ~FakeTouchIdContext() override;
 
   // TouchIdContext:
@@ -31,8 +34,6 @@
   FakeTouchIdContext();
 
   bool callback_result_ = true;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeTouchIdContext);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/get_assertion_operation.h b/device/fido/mac/get_assertion_operation.h
index 3ac2e20..47f162c9 100644
--- a/device/fido/mac/get_assertion_operation.h
+++ b/device/fido/mac/get_assertion_operation.h
@@ -39,6 +39,10 @@
   GetAssertionOperation(CtapGetAssertionRequest request,
                         TouchIdCredentialStore* credential_store,
                         Callback callback);
+
+  GetAssertionOperation(const GetAssertionOperation&) = delete;
+  GetAssertionOperation& operator=(const GetAssertionOperation&) = delete;
+
   ~GetAssertionOperation() override;
 
   // Operation:
@@ -60,8 +64,6 @@
   TouchIdCredentialStore* const credential_store_;
   Callback callback_;
   std::list<Credential> matching_credentials_;
-
-  DISALLOW_COPY_AND_ASSIGN(GetAssertionOperation);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/make_credential_operation.h b/device/fido/mac/make_credential_operation.h
index 921af42d4..ed030ad 100644
--- a/device/fido/mac/make_credential_operation.h
+++ b/device/fido/mac/make_credential_operation.h
@@ -56,6 +56,10 @@
   MakeCredentialOperation(CtapMakeCredentialRequest request,
                           TouchIdCredentialStore* credential_store,
                           Callback callback);
+
+  MakeCredentialOperation(const MakeCredentialOperation&) = delete;
+  MakeCredentialOperation& operator=(const MakeCredentialOperation&) = delete;
+
   ~MakeCredentialOperation() override;
 
   // Operation:
@@ -70,8 +74,6 @@
   const CtapMakeCredentialRequest request_;
   TouchIdCredentialStore* const credential_store_;
   Callback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(MakeCredentialOperation);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/operation.h b/device/fido/mac/operation.h
index c62a2c9..3a72a32 100644
--- a/device/fido/mac/operation.h
+++ b/device/fido/mac/operation.h
@@ -14,11 +14,12 @@
 class Operation {
  public:
   Operation() = default;
+
+  Operation(const Operation&) = delete;
+  Operation& operator=(const Operation&) = delete;
+
   virtual ~Operation() = default;
   virtual void Run() = 0;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Operation);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/scoped_touch_id_test_environment.h b/device/fido/mac/scoped_touch_id_test_environment.h
index 6512d5c..1decedc8 100644
--- a/device/fido/mac/scoped_touch_id_test_environment.h
+++ b/device/fido/mac/scoped_touch_id_test_environment.h
@@ -32,6 +32,11 @@
     API_AVAILABLE(macosx(10.12.2)) ScopedTouchIdTestEnvironment {
  public:
   ScopedTouchIdTestEnvironment();
+
+  ScopedTouchIdTestEnvironment(const ScopedTouchIdTestEnvironment&) = delete;
+  ScopedTouchIdTestEnvironment& operator=(const ScopedTouchIdTestEnvironment&) =
+      delete;
+
   ~ScopedTouchIdTestEnvironment();
 
   // ForgeNextTouchIdContext sets up the FakeTouchIdContext returned by the
@@ -61,8 +66,6 @@
   std::unique_ptr<FakeTouchIdContext> next_touch_id_context_;
   std::unique_ptr<FakeKeychain> keychain_;
   bool touch_id_available_ = true;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedTouchIdTestEnvironment);
 };
 
 }  // namespace mac
diff --git a/device/fido/mac/touch_id_context.h b/device/fido/mac/touch_id_context.h
index 7908691..12adcc9 100644
--- a/device/fido/mac/touch_id_context.h
+++ b/device/fido/mac/touch_id_context.h
@@ -50,6 +50,9 @@
   static void TouchIdAvailable(AuthenticatorConfig config,
                                base::OnceCallback<void(bool is_available)>);
 
+  TouchIdContext(const TouchIdContext&) = delete;
+  TouchIdContext& operator=(const TouchIdContext&) = delete;
+
   virtual ~TouchIdContext();
 
   // PromptTouchId displays a local user authentication prompt with the provided
@@ -87,7 +90,6 @@
   base::WeakPtrFactory<TouchIdContext> weak_ptr_factory_;
 
   friend class ScopedTouchIdTestEnvironment;
-  DISALLOW_COPY_AND_ASSIGN(TouchIdContext);
 };
 
 }  // namespace mac
diff --git a/device/fido/make_credential_request_handler.h b/device/fido/make_credential_request_handler.h
index c424ce6..f9cc637 100644
--- a/device/fido/make_credential_request_handler.h
+++ b/device/fido/make_credential_request_handler.h
@@ -77,6 +77,11 @@
       CtapMakeCredentialRequest request_parameter,
       const MakeCredentialOptions& options,
       CompletionCallback completion_callback);
+
+  MakeCredentialRequestHandler(const MakeCredentialRequestHandler&) = delete;
+  MakeCredentialRequestHandler& operator=(const MakeCredentialRequestHandler&) =
+      delete;
+
   ~MakeCredentialRequestHandler() override;
 
  private:
@@ -170,8 +175,6 @@
 
   SEQUENCE_CHECKER(my_sequence_checker_);
   base::WeakPtrFactory<MakeCredentialRequestHandler> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(MakeCredentialRequestHandler);
 };
 
 }  // namespace device
diff --git a/device/fido/make_credential_task.h b/device/fido/make_credential_task.h
index 878fe9e5..3d1acf8 100644
--- a/device/fido/make_credential_task.h
+++ b/device/fido/make_credential_task.h
@@ -42,6 +42,10 @@
                      CtapMakeCredentialRequest request,
                      MakeCredentialOptions options,
                      MakeCredentialTaskCallback callback);
+
+  MakeCredentialTask(const MakeCredentialTask&) = delete;
+  MakeCredentialTask& operator=(const MakeCredentialTask&) = delete;
+
   ~MakeCredentialTask() override;
 
   // GetTouchRequest returns a request that will cause a device to flash and
@@ -87,8 +91,6 @@
   bool canceled_ = false;
 
   base::WeakPtrFactory<MakeCredentialTask> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(MakeCredentialTask);
 };
 
 // FilterAndBatchCredentialDescriptors splits a list of
diff --git a/device/fido/mock_fido_device.h b/device/fido/mock_fido_device.h
index 3b8750a..8b331ab 100644
--- a/device/fido/mock_fido_device.h
+++ b/device/fido/mock_fido_device.h
@@ -58,6 +58,10 @@
   MockFidoDevice();
   MockFidoDevice(ProtocolVersion protocol_version,
                  absl::optional<AuthenticatorGetInfoResponse> device_info);
+
+  MockFidoDevice(const MockFidoDevice&) = delete;
+  MockFidoDevice& operator=(const MockFidoDevice&) = delete;
+
   ~MockFidoDevice() override;
 
   // TODO(crbug.com/729950): Remove these workarounds once support for move-only
@@ -106,8 +110,6 @@
   FidoTransportProtocol transport_protocol_ =
       FidoTransportProtocol::kUsbHumanInterfaceDevice;
   base::WeakPtrFactory<FidoDevice> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(MockFidoDevice);
 };
 
 }  // namespace device
diff --git a/device/fido/mock_fido_discovery_observer.h b/device/fido/mock_fido_discovery_observer.h
index 6be1988..3f942e88 100644
--- a/device/fido/mock_fido_discovery_observer.h
+++ b/device/fido/mock_fido_discovery_observer.h
@@ -20,6 +20,11 @@
 class MockFidoDiscoveryObserver : public FidoDiscoveryBase::Observer {
  public:
   MockFidoDiscoveryObserver();
+
+  MockFidoDiscoveryObserver(const MockFidoDiscoveryObserver&) = delete;
+  MockFidoDiscoveryObserver& operator=(const MockFidoDiscoveryObserver&) =
+      delete;
+
   ~MockFidoDiscoveryObserver() override;
 
   MOCK_METHOD3(DiscoveryStarted,
@@ -33,9 +38,6 @@
                void(FidoDiscoveryBase*, const std::string&, std::string));
   MOCK_METHOD3(AuthenticatorPairingModeChanged,
                void(FidoDiscoveryBase*, const std::string&, bool));
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockFidoDiscoveryObserver);
 };
 
 }  // namespace device
diff --git a/device/fido/opaque_attestation_statement.h b/device/fido/opaque_attestation_statement.h
index f97bdf2..ddac9ce4 100644
--- a/device/fido/opaque_attestation_statement.h
+++ b/device/fido/opaque_attestation_statement.h
@@ -20,6 +20,11 @@
  public:
   OpaqueAttestationStatement(std::string attestation_format,
                              cbor::Value attestation_statement_map);
+
+  OpaqueAttestationStatement(const OpaqueAttestationStatement&) = delete;
+  OpaqueAttestationStatement& operator=(const OpaqueAttestationStatement&) =
+      delete;
+
   ~OpaqueAttestationStatement() override;
 
   // AttestationStatement:
@@ -30,8 +35,6 @@
 
  private:
   cbor::Value attestation_statement_map_;
-
-  DISALLOW_COPY_AND_ASSIGN(OpaqueAttestationStatement);
 };
 
 }  // namespace device
diff --git a/device/fido/reset_request_handler.h b/device/fido/reset_request_handler.h
index 173d904..3d42705 100644
--- a/device/fido/reset_request_handler.h
+++ b/device/fido/reset_request_handler.h
@@ -47,6 +47,10 @@
       FinishedCallback finished_callback,
       std::unique_ptr<FidoDiscoveryFactory> fido_discovery_factory =
           std::make_unique<FidoDiscoveryFactory>());
+
+  ResetRequestHandler(const ResetRequestHandler&) = delete;
+  ResetRequestHandler& operator=(const ResetRequestHandler&) = delete;
+
   ~ResetRequestHandler() override;
 
  private:
@@ -63,8 +67,6 @@
   std::unique_ptr<FidoDiscoveryFactory> fido_discovery_factory_;
   SEQUENCE_CHECKER(my_sequence_checker_);
   base::WeakPtrFactory<ResetRequestHandler> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(ResetRequestHandler);
 };
 
 }  // namespace device
diff --git a/device/fido/set_pin_request_handler.h b/device/fido/set_pin_request_handler.h
index e841e054..050aee5 100644
--- a/device/fido/set_pin_request_handler.h
+++ b/device/fido/set_pin_request_handler.h
@@ -66,6 +66,10 @@
       FinishedCallback finished_callback,
       std::unique_ptr<FidoDiscoveryFactory> fido_discovery_factory =
           std::make_unique<FidoDiscoveryFactory>());
+
+  SetPINRequestHandler(const SetPINRequestHandler&) = delete;
+  SetPINRequestHandler& operator=(const SetPINRequestHandler&) = delete;
+
   ~SetPINRequestHandler() override;
 
   // ProvidePIN may be called after |get_pin_callback| has been used to indicate
@@ -106,8 +110,6 @@
   std::unique_ptr<FidoDiscoveryFactory> fido_discovery_factory_;
   SEQUENCE_CHECKER(my_sequence_checker_);
   base::WeakPtrFactory<SetPINRequestHandler> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(SetPINRequestHandler);
 };
 
 }  // namespace device
diff --git a/device/fido/test_callback_receiver.h b/device/fido/test_callback_receiver.h
index d006268..989a97d 100644
--- a/device/fido/test_callback_receiver.h
+++ b/device/fido/test_callback_receiver.h
@@ -43,6 +43,10 @@
   using TupleOfNonReferenceArgs = std::tuple<std::decay_t<CallbackArgs>...>;
 
   TestCallbackReceiver() = default;
+
+  TestCallbackReceiver(const TestCallbackReceiver&) = delete;
+  TestCallbackReceiver& operator=(const TestCallbackReceiver&) = delete;
+
   ~TestCallbackReceiver() = default;
 
   // Whether the |callback| was already called.
@@ -89,8 +93,6 @@
   bool was_called_ = false;
   base::RunLoop wait_for_callback_loop_;
   absl::optional<TupleOfNonReferenceArgs> result_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestCallbackReceiver);
 };
 
 template <class Value>
diff --git a/device/fido/u2f_register_operation.h b/device/fido/u2f_register_operation.h
index c2348327..2c1d59b 100644
--- a/device/fido/u2f_register_operation.h
+++ b/device/fido/u2f_register_operation.h
@@ -34,6 +34,10 @@
   U2fRegisterOperation(FidoDevice* device,
                        const CtapMakeCredentialRequest& request,
                        DeviceResponseCallback callback);
+
+  U2fRegisterOperation(const U2fRegisterOperation&) = delete;
+  U2fRegisterOperation& operator=(const U2fRegisterOperation&) = delete;
+
   ~U2fRegisterOperation() override;
 
   // DeviceOperation:
@@ -61,8 +65,6 @@
   // ID.
   bool probing_alternative_rp_id_ = false;
   base::WeakPtrFactory<U2fRegisterOperation> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(U2fRegisterOperation);
 };
 
 }  // namespace device
diff --git a/device/fido/u2f_sign_operation.h b/device/fido/u2f_sign_operation.h
index 6026177..3192c48 100644
--- a/device/fido/u2f_sign_operation.h
+++ b/device/fido/u2f_sign_operation.h
@@ -34,6 +34,10 @@
   U2fSignOperation(FidoDevice* device,
                    const CtapGetAssertionRequest& request,
                    DeviceResponseCallback callback);
+
+  U2fSignOperation(const U2fSignOperation&) = delete;
+  U2fSignOperation& operator=(const U2fSignOperation&) = delete;
+
   ~U2fSignOperation() override;
 
   // DeviceOperation:
@@ -57,8 +61,6 @@
   ApplicationParameterType app_param_type_ = ApplicationParameterType::kPrimary;
   bool canceled_ = false;
   base::WeakPtrFactory<U2fSignOperation> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(U2fSignOperation);
 };
 
 }  // namespace device
diff --git a/device/fido/virtual_ctap2_device.h b/device/fido/virtual_ctap2_device.h
index 2d152220..fadf688 100644
--- a/device/fido/virtual_ctap2_device.h
+++ b/device/fido/virtual_ctap2_device.h
@@ -198,6 +198,10 @@
 
   VirtualCtap2Device();
   VirtualCtap2Device(scoped_refptr<State> state, const Config& config);
+
+  VirtualCtap2Device(const VirtualCtap2Device&) = delete;
+  VirtualCtap2Device& operator=(const VirtualCtap2Device&) = delete;
+
   ~VirtualCtap2Device() override;
 
   // Configures and sets a PIN on the authenticator.
@@ -317,8 +321,6 @@
   const Config config_;
   RequestState request_state_;
   base::WeakPtrFactory<FidoDevice> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(VirtualCtap2Device);
 };
 
 }  // namespace device
diff --git a/device/fido/virtual_fido_device.h b/device/fido/virtual_fido_device.h
index 11191bbe..e0eacfa 100644
--- a/device/fido/virtual_fido_device.h
+++ b/device/fido/virtual_fido_device.h
@@ -94,6 +94,9 @@
     RegistrationData(RegistrationData&& data);
     RegistrationData& operator=(RegistrationData&& other);
 
+    RegistrationData(const RegistrationData&) = delete;
+    RegistrationData& operator=(const RegistrationData&) = delete;
+
     ~RegistrationData();
 
     std::unique_ptr<PrivateKey> private_key = PrivateKey::FreshP256Key();
@@ -117,8 +120,6 @@
 
     absl::optional<std::array<uint8_t, 32>> large_blob_key;
     absl::optional<std::vector<uint8_t>> cred_blob;
-
-    DISALLOW_COPY_AND_ASSIGN(RegistrationData);
   };
 
   // Stores the state of the device. Since |U2fDevice| objects only persist for
diff --git a/device/fido/virtual_fido_device_factory.h b/device/fido/virtual_fido_device_factory.h
index 82958de2..003a832 100644
--- a/device/fido/virtual_fido_device_factory.h
+++ b/device/fido/virtual_fido_device_factory.h
@@ -21,6 +21,10 @@
 class VirtualFidoDeviceFactory : public device::FidoDiscoveryFactory {
  public:
   VirtualFidoDeviceFactory();
+
+  VirtualFidoDeviceFactory(const VirtualFidoDeviceFactory&) = delete;
+  VirtualFidoDeviceFactory& operator=(const VirtualFidoDeviceFactory&) = delete;
+
   ~VirtualFidoDeviceFactory() override;
 
   // Sets the FidoTransportProtocol of the FidoDiscovery to be instantiated by
@@ -49,7 +53,6 @@
       FidoTransportProtocol::kUsbHumanInterfaceDevice;
   VirtualCtap2Device::Config ctap2_config_;
   scoped_refptr<VirtualFidoDevice::State> state_ = new VirtualFidoDevice::State;
-  DISALLOW_COPY_AND_ASSIGN(VirtualFidoDeviceFactory);
 };
 
 }  // namespace test
diff --git a/device/fido/virtual_u2f_device.h b/device/fido/virtual_u2f_device.h
index bce29c9..bba7a75 100644
--- a/device/fido/virtual_u2f_device.h
+++ b/device/fido/virtual_u2f_device.h
@@ -26,6 +26,10 @@
 
   VirtualU2fDevice();
   explicit VirtualU2fDevice(scoped_refptr<State> state);
+
+  VirtualU2fDevice(const VirtualU2fDevice&) = delete;
+  VirtualU2fDevice& operator=(const VirtualU2fDevice&) = delete;
+
   ~VirtualU2fDevice() override;
 
   // FidoDevice:
@@ -47,8 +51,6 @@
                                               base::span<const uint8_t> data);
 
   base::WeakPtrFactory<FidoDevice> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(VirtualU2fDevice);
 };
 
 }  // namespace device
diff --git a/device/fido/win/authenticator.h b/device/fido/win/authenticator.h
index 5522111..cf055c4 100644
--- a/device/fido/win/authenticator.h
+++ b/device/fido/win/authenticator.h
@@ -41,6 +41,11 @@
   // Callers must ensure that WinWebAuthnApi::IsAvailable() returns true
   // before creating instances of this class.
   WinWebAuthnApiAuthenticator(HWND current_window, WinWebAuthnApi* win_api_);
+
+  WinWebAuthnApiAuthenticator(const WinWebAuthnApiAuthenticator&) = delete;
+  WinWebAuthnApiAuthenticator& operator=(const WinWebAuthnApiAuthenticator&) =
+      delete;
+
   ~WinWebAuthnApiAuthenticator() override;
 
   // ShowsPrivacyNotice returns true if the Windows native UI will show a
@@ -96,7 +101,6 @@
   // sequence.
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<WinWebAuthnApiAuthenticator> weak_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(WinWebAuthnApiAuthenticator);
 };
 
 }  // namespace device
diff --git a/device/gamepad/gamepad_haptics_manager.h b/device/gamepad/gamepad_haptics_manager.h
index 7e7d8e3..69617bc1 100644
--- a/device/gamepad/gamepad_haptics_manager.h
+++ b/device/gamepad/gamepad_haptics_manager.h
@@ -15,6 +15,10 @@
     : public mojom::GamepadHapticsManager {
  public:
   GamepadHapticsManager();
+
+  GamepadHapticsManager(const GamepadHapticsManager&) = delete;
+  GamepadHapticsManager& operator=(const GamepadHapticsManager&) = delete;
+
   ~GamepadHapticsManager() override;
 
   static void Create(
@@ -27,9 +31,6 @@
                                PlayVibrationEffectOnceCallback) override;
   void ResetVibrationActuator(uint32_t pad_index,
                               ResetVibrationActuatorCallback) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GamepadHapticsManager);
 };
 
 }  // namespace device
diff --git a/device/gamepad/gamepad_monitor.h b/device/gamepad/gamepad_monitor.h
index df120f23..dc7bffb 100644
--- a/device/gamepad/gamepad_monitor.h
+++ b/device/gamepad/gamepad_monitor.h
@@ -19,6 +19,10 @@
                                              public mojom::GamepadMonitor {
  public:
   GamepadMonitor();
+
+  GamepadMonitor(const GamepadMonitor&) = delete;
+  GamepadMonitor& operator=(const GamepadMonitor&) = delete;
+
   ~GamepadMonitor() override;
 
   static void Create(mojo::PendingReceiver<mojom::GamepadMonitor> receiver);
@@ -42,8 +46,6 @@
 
   // True if this monitor has been registered with the gamepad service.
   bool is_registered_consumer_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(GamepadMonitor);
 };
 
 }  // namespace device
diff --git a/device/gamepad/gamepad_platform_data_fetcher_mac.h b/device/gamepad/gamepad_platform_data_fetcher_mac.h
index 67b6c12e..bc77b6e 100644
--- a/device/gamepad/gamepad_platform_data_fetcher_mac.h
+++ b/device/gamepad/gamepad_platform_data_fetcher_mac.h
@@ -32,6 +32,11 @@
                                                 GAMEPAD_SOURCE_MAC_HID>;
 
   GamepadPlatformDataFetcherMac();
+
+  GamepadPlatformDataFetcherMac(const GamepadPlatformDataFetcherMac&) = delete;
+  GamepadPlatformDataFetcherMac& operator=(
+      const GamepadPlatformDataFetcherMac&) = delete;
+
   ~GamepadPlatformDataFetcherMac() override;
 
   // GamepadDataFetcher public implementation.
@@ -95,8 +100,6 @@
 
   // A map of all devices using this data fetcher with the source_id as the key.
   std::unordered_map<int, std::unique_ptr<GamepadDeviceMac>> devices_;
-
-  DISALLOW_COPY_AND_ASSIGN(GamepadPlatformDataFetcherMac);
 };
 
 }  // namespace device
diff --git a/device/gamepad/gamepad_service.h b/device/gamepad/gamepad_service.h
index 93b8496a..40d2efad 100644
--- a/device/gamepad/gamepad_service.h
+++ b/device/gamepad/gamepad_service.h
@@ -112,6 +112,9 @@
   // provider, bypassing the default platform one.
   GamepadService(std::unique_ptr<GamepadDataFetcher> fetcher);
 
+  GamepadService(const GamepadService&) = delete;
+  GamepadService& operator=(const GamepadService&) = delete;
+
   virtual ~GamepadService();
 
  private:
@@ -158,8 +161,6 @@
   int num_active_consumers_ = 0;
 
   bool gesture_callback_pending_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(GamepadService);
 };
 
 }  // namespace device
diff --git a/device/gamepad/gamepad_test_helpers.h b/device/gamepad/gamepad_test_helpers.h
index 98873fa..9dbe199 100644
--- a/device/gamepad/gamepad_test_helpers.h
+++ b/device/gamepad/gamepad_test_helpers.h
@@ -23,6 +23,9 @@
   // returned when the provider queries us.
   explicit MockGamepadDataFetcher(const Gamepads& test_data);
 
+  MockGamepadDataFetcher(const MockGamepadDataFetcher&) = delete;
+  MockGamepadDataFetcher& operator=(const MockGamepadDataFetcher&) = delete;
+
   ~MockGamepadDataFetcher() override;
 
   GamepadSource source() override;
@@ -46,21 +49,21 @@
   base::Lock lock_;
   Gamepads test_data_;
   base::WaitableEvent read_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(MockGamepadDataFetcher);
 };
 
 // Base class for the other test helpers. This just sets up the system monitor.
 class GamepadTestHelper {
  public:
   GamepadTestHelper();
+
+  GamepadTestHelper(const GamepadTestHelper&) = delete;
+  GamepadTestHelper& operator=(const GamepadTestHelper&) = delete;
+
   virtual ~GamepadTestHelper();
 
  private:
   // This must be constructed before the system monitor.
   base::test::SingleThreadTaskEnvironment task_environment_;
-
-  DISALLOW_COPY_AND_ASSIGN(GamepadTestHelper);
 };
 
 // Constructs a GamepadService with a mock data source. This bypasses the
@@ -68,6 +71,11 @@
 class GamepadServiceTestConstructor : public GamepadTestHelper {
  public:
   explicit GamepadServiceTestConstructor(const Gamepads& test_data);
+
+  GamepadServiceTestConstructor(const GamepadServiceTestConstructor&) = delete;
+  GamepadServiceTestConstructor& operator=(
+      const GamepadServiceTestConstructor&) = delete;
+
   ~GamepadServiceTestConstructor() override;
 
   GamepadService* gamepad_service() { return gamepad_service_; }
@@ -79,8 +87,6 @@
 
   // Pointer owned by the provider (which is owned by the gamepad service).
   MockGamepadDataFetcher* data_fetcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(GamepadServiceTestConstructor);
 };
 
 }  // namespace device
diff --git a/device/gamepad/nintendo_data_fetcher.h b/device/gamepad/nintendo_data_fetcher.h
index b3c86b9..3f1a525 100644
--- a/device/gamepad/nintendo_data_fetcher.h
+++ b/device/gamepad/nintendo_data_fetcher.h
@@ -50,6 +50,10 @@
       std::unordered_map<int, std::unique_ptr<NintendoController>>;
 
   NintendoDataFetcher();
+
+  NintendoDataFetcher(const NintendoDataFetcher&) = delete;
+  NintendoDataFetcher& operator=(const NintendoDataFetcher&) = delete;
+
   ~NintendoDataFetcher() override;
 
   // Add the newly-connected HID device described by |device_info|. Returns
@@ -115,8 +119,6 @@
   mojo::Remote<mojom::HidManager> hid_manager_;
   mojo::AssociatedReceiver<mojom::HidManagerClient> receiver_{this};
   base::WeakPtrFactory<NintendoDataFetcher> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(NintendoDataFetcher);
 };
 
 }  // namespace device
diff --git a/device/gamepad/xinput_data_fetcher_win.h b/device/gamepad/xinput_data_fetcher_win.h
index 55f9a57..abc800f4 100644
--- a/device/gamepad/xinput_data_fetcher_win.h
+++ b/device/gamepad/xinput_data_fetcher_win.h
@@ -53,6 +53,10 @@
       Factory;
 
   XInputDataFetcherWin();
+
+  XInputDataFetcherWin(const XInputDataFetcherWin&) = delete;
+  XInputDataFetcherWin& operator=(const XInputDataFetcherWin&) = delete;
+
   ~XInputDataFetcherWin() override;
 
   GamepadSource source() override;
@@ -105,8 +109,6 @@
 
   bool xinput_connected_[XUSER_MAX_COUNT];
   std::unique_ptr<XInputHapticGamepadWin> haptics_[XUSER_MAX_COUNT];
-
-  DISALLOW_COPY_AND_ASSIGN(XInputDataFetcherWin);
 };
 
 }  // namespace device
diff --git a/device/test/run_all_unittests.cc b/device/test/run_all_unittests.cc
index d203d479..76978e1 100644
--- a/device/test/run_all_unittests.cc
+++ b/device/test/run_all_unittests.cc
@@ -19,6 +19,10 @@
 class DeviceTestSuite : public base::TestSuite {
  public:
   DeviceTestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {}
+
+  DeviceTestSuite(const DeviceTestSuite&) = delete;
+  DeviceTestSuite& operator=(const DeviceTestSuite&) = delete;
+
   ~DeviceTestSuite() override = default;
 
  protected:
@@ -52,9 +56,6 @@
 
     base::TestSuite::Shutdown();
   }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DeviceTestSuite);
 };
 
 }  // namespace
diff --git a/device/udev_linux/udev0_loader.h b/device/udev_linux/udev0_loader.h
index 4126092..19f2750 100644
--- a/device/udev_linux/udev0_loader.h
+++ b/device/udev_linux/udev0_loader.h
@@ -17,6 +17,10 @@
 class Udev0Loader : public UdevLoader {
  public:
   Udev0Loader();
+
+  Udev0Loader(const Udev0Loader&) = delete;
+  Udev0Loader& operator=(const Udev0Loader&) = delete;
+
   ~Udev0Loader() override;
 
  private:
@@ -77,8 +81,6 @@
   void udev_unref(udev* udev) override;
 
   std::unique_ptr<LibUdev0Loader> lib_loader_;
-
-  DISALLOW_COPY_AND_ASSIGN(Udev0Loader);
 };
 
 }  // namespace device
diff --git a/device/udev_linux/udev1_loader.h b/device/udev_linux/udev1_loader.h
index c082075..f5faefa 100644
--- a/device/udev_linux/udev1_loader.h
+++ b/device/udev_linux/udev1_loader.h
@@ -17,6 +17,10 @@
 class Udev1Loader : public UdevLoader {
  public:
   Udev1Loader();
+
+  Udev1Loader(const Udev1Loader&) = delete;
+  Udev1Loader& operator=(const Udev1Loader&) = delete;
+
   ~Udev1Loader() override;
 
  private:
@@ -77,8 +81,6 @@
   void udev_unref(udev* udev) override;
 
   std::unique_ptr<LibUdev1Loader> lib_loader_;
-
-  DISALLOW_COPY_AND_ASSIGN(Udev1Loader);
 };
 
 }  // namespace device
diff --git a/device/vr/android/arcore/ar_image_transport.h b/device/vr/android/arcore/ar_image_transport.h
index 500cbe6..621b12c 100644
--- a/device/vr/android/arcore/ar_image_transport.h
+++ b/device/vr/android/arcore/ar_image_transport.h
@@ -48,6 +48,10 @@
 
   explicit ArImageTransport(
       std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge);
+
+  ArImageTransport(const ArImageTransport&) = delete;
+  ArImageTransport& operator=(const ArImageTransport&) = delete;
+
   virtual ~ArImageTransport();
 
   virtual void DestroySharedBuffers(WebXrPresentationState* webxr);
@@ -132,7 +136,6 @@
 
   // Must be last.
   base::WeakPtrFactory<ArImageTransport> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(ArImageTransport);
 };
 
 class COMPONENT_EXPORT(VR_ARCORE) ArImageTransportFactory {
diff --git a/device/vr/android/arcore/ar_renderer.h b/device/vr/android/arcore/ar_renderer.h
index b1365bc..699ed4e 100644
--- a/device/vr/android/arcore/ar_renderer.h
+++ b/device/vr/android/arcore/ar_renderer.h
@@ -15,6 +15,10 @@
 class ArRenderer {
  public:
   ArRenderer();
+
+  ArRenderer(const ArRenderer&) = delete;
+  ArRenderer& operator=(const ArRenderer&) = delete;
+
   ~ArRenderer();
 
   void Draw(int texture_handle, const float (&uv_transform)[16]);
@@ -27,8 +31,6 @@
   GLuint uv_transform_ = 0;
   GLuint vertex_buffer_ = 0;
   GLuint index_buffer_ = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(ArRenderer);
 };
 
 }  // namespace device
diff --git a/device/vr/android/arcore/arcore_device.h b/device/vr/android/arcore/arcore_device.h
index 39ca446..0a0788f 100644
--- a/device/vr/android/arcore/arcore_device.h
+++ b/device/vr/android/arcore/arcore_device.h
@@ -46,6 +46,10 @@
           mailbox_to_surface_bridge_factory,
       std::unique_ptr<ArCoreSessionUtils> arcore_session_utils,
       XrFrameSinkClientFactory xr_frame_sink_client_factory);
+
+  ArCoreDevice(const ArCoreDevice&) = delete;
+  ArCoreDevice& operator=(const ArCoreDevice&) = delete;
+
   ~ArCoreDevice() override;
 
   // VRDeviceBase implementation.
@@ -176,7 +180,6 @@
 
   // Must be last.
   base::WeakPtrFactory<ArCoreDevice> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(ArCoreDevice);
 };
 
 }  // namespace device
diff --git a/device/vr/android/arcore/arcore_gl.h b/device/vr/android/arcore/arcore_gl.h
index c6254412..88bf19e 100644
--- a/device/vr/android/arcore/arcore_gl.h
+++ b/device/vr/android/arcore/arcore_gl.h
@@ -94,6 +94,10 @@
                  public mojom::XRSessionController {
  public:
   explicit ArCoreGl(std::unique_ptr<ArImageTransport> ar_image_transport);
+
+  ArCoreGl(const ArCoreGl&) = delete;
+  ArCoreGl& operator=(const ArCoreGl&) = delete;
+
   ~ArCoreGl() override;
 
   void Initialize(
@@ -416,7 +420,6 @@
 
   // Must be last.
   base::WeakPtrFactory<ArCoreGl> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(ArCoreGl);
 };
 
 }  // namespace device
diff --git a/device/vr/android/arcore/arcore_gl_thread.h b/device/vr/android/arcore/arcore_gl_thread.h
index a8a8578..5beae113 100644
--- a/device/vr/android/arcore/arcore_gl_thread.h
+++ b/device/vr/android/arcore/arcore_gl_thread.h
@@ -24,6 +24,10 @@
       std::unique_ptr<ArImageTransportFactory> ar_image_transport_factory,
       std::unique_ptr<MailboxToSurfaceBridge> mailbox_bridge,
       base::OnceCallback<void()> initialized_callback);
+
+  ArCoreGlThread(const ArCoreGlThread&) = delete;
+  ArCoreGlThread& operator=(const ArCoreGlThread&) = delete;
+
   ~ArCoreGlThread() override;
   ArCoreGl* GetArCoreGl();
 
@@ -38,8 +42,6 @@
 
   // Created on GL thread.
   std::unique_ptr<ArCoreGl> arcore_gl_;
-
-  DISALLOW_COPY_AND_ASSIGN(ArCoreGlThread);
 };
 
 }  // namespace device
diff --git a/device/vr/android/arcore/arcore_impl.h b/device/vr/android/arcore/arcore_impl.h
index 8293847..2c3692f6 100644
--- a/device/vr/android/arcore/arcore_impl.h
+++ b/device/vr/android/arcore/arcore_impl.h
@@ -77,6 +77,10 @@
 class ArCoreImpl : public ArCore {
  public:
   ArCoreImpl();
+
+  ArCoreImpl(const ArCoreImpl&) = delete;
+  ArCoreImpl& operator=(const ArCoreImpl&) = delete;
+
   ~ArCoreImpl() override;
 
   absl::optional<ArCore::InitializeResult> Initialize(
@@ -322,7 +326,6 @@
 
   // Must be last.
   base::WeakPtrFactory<ArCoreImpl> weak_ptr_factory_{this};
-  DISALLOW_COPY_AND_ASSIGN(ArCoreImpl);
 };
 
 // TODO(https://crbug.com/843374): Once the arcore_device class is moved,
diff --git a/device/vr/android/gvr/gvr_delegate_provider_factory.h b/device/vr/android/gvr/gvr_delegate_provider_factory.h
index 755f9e42..ba0ee74 100644
--- a/device/vr/android/gvr/gvr_delegate_provider_factory.h
+++ b/device/vr/android/gvr/gvr_delegate_provider_factory.h
@@ -23,6 +23,10 @@
   static void SetDevice(GvrDevice* device) { device_ = device; }
   static GvrDevice* GetDevice() { return device_; }
 
+  GvrDelegateProviderFactory(const GvrDelegateProviderFactory&) = delete;
+  GvrDelegateProviderFactory& operator=(const GvrDelegateProviderFactory&) =
+      delete;
+
   virtual ~GvrDelegateProviderFactory() = default;
 
  protected:
@@ -31,9 +35,6 @@
   virtual GvrDelegateProvider* CreateGvrDelegateProvider() = 0;
 
   static GvrDevice* device_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GvrDelegateProviderFactory);
 };
 
 }  // namespace device
diff --git a/device/vr/android/gvr/gvr_device.h b/device/vr/android/gvr/gvr_device.h
index eaf8de7..3cb028b 100644
--- a/device/vr/android/gvr/gvr_device.h
+++ b/device/vr/android/gvr/gvr_device.h
@@ -24,6 +24,10 @@
                                    public mojom::XRSessionController {
  public:
   GvrDevice();
+
+  GvrDevice(const GvrDevice&) = delete;
+  GvrDevice& operator=(const GvrDevice&) = delete;
+
   ~GvrDevice() override;
 
   // VRDeviceBase
@@ -65,8 +69,6 @@
   mojom::XRRuntime::RequestSessionCallback pending_request_session_callback_;
 
   base::WeakPtrFactory<GvrDevice> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(GvrDevice);
 };
 
 }  // namespace device
diff --git a/device/vr/android/gvr/gvr_device_provider.h b/device/vr/android/gvr/gvr_device_provider.h
index 04e2f7819..8eb2f51 100644
--- a/device/vr/android/gvr/gvr_device_provider.h
+++ b/device/vr/android/gvr/gvr_device_provider.h
@@ -19,6 +19,10 @@
 class DEVICE_VR_EXPORT GvrDeviceProvider : public VRDeviceProvider {
  public:
   GvrDeviceProvider();
+
+  GvrDeviceProvider(const GvrDeviceProvider&) = delete;
+  GvrDeviceProvider& operator=(const GvrDeviceProvider&) = delete;
+
   ~GvrDeviceProvider() override;
 
   void Initialize(
@@ -36,8 +40,6 @@
  private:
   std::unique_ptr<GvrDevice> vr_device_;
   bool initialized_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(GvrDeviceProvider);
 };
 
 }  // namespace device
diff --git a/device/vr/android/web_xr_presentation_state.h b/device/vr/android/web_xr_presentation_state.h
index 0af7431..237fcddb 100644
--- a/device/vr/android/web_xr_presentation_state.h
+++ b/device/vr/android/web_xr_presentation_state.h
@@ -189,6 +189,10 @@
   static constexpr int kWebXrFrameCount = 3;
 
   WebXrPresentationState();
+
+  WebXrPresentationState(const WebXrPresentationState&) = delete;
+  WebXrPresentationState& operator=(const WebXrPresentationState&) = delete;
+
   ~WebXrPresentationState();
 
   void SetStateMachineType(StateMachineType type);
@@ -266,8 +270,6 @@
   base::queue<WebXrFrame*> idle_frames_;
 
   bool mailbox_bridge_ready_ = false;
-
-  DISALLOW_COPY_AND_ASSIGN(WebXrPresentationState);
 };
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_anchor_manager.h b/device/vr/openxr/openxr_anchor_manager.h
index fb4bc2c..d106b6a 100644
--- a/device/vr/openxr/openxr_anchor_manager.h
+++ b/device/vr/openxr/openxr_anchor_manager.h
@@ -23,6 +23,10 @@
   OpenXrAnchorManager(const OpenXrExtensionHelper& extension_helper,
                       XrSession session,
                       XrSpace mojo_space);
+
+  OpenXrAnchorManager(const OpenXrAnchorManager&) = delete;
+  OpenXrAnchorManager& operator=(const OpenXrAnchorManager&) = delete;
+
   ~OpenXrAnchorManager();
 
   void AddCreateAnchorRequest(
@@ -89,7 +93,6 @@
 
   AnchorId::Generator anchor_id_generator_;  // 0 is not a valid anchor ID
   std::map<AnchorId, AnchorData> openxr_anchors_;
-  DISALLOW_COPY_AND_ASSIGN(OpenXrAnchorManager);
 };
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_api_wrapper.h b/device/vr/openxr/openxr_api_wrapper.h
index 16ee3cf..f798fe6 100644
--- a/device/vr/openxr/openxr_api_wrapper.h
+++ b/device/vr/openxr/openxr_api_wrapper.h
@@ -45,6 +45,10 @@
 class OpenXrApiWrapper {
  public:
   OpenXrApiWrapper();
+
+  OpenXrApiWrapper(const OpenXrApiWrapper&) = delete;
+  OpenXrApiWrapper& operator=(const OpenXrApiWrapper&) = delete;
+
   ~OpenXrApiWrapper();
   bool IsInitialized() const;
 
@@ -206,8 +210,6 @@
   std::unique_ptr<OpenXRSceneUnderstandingManager> scene_understanding_manager_;
 
   base::WeakPtrFactory<OpenXrApiWrapper> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(OpenXrApiWrapper);
 };
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_controller.h b/device/vr/openxr/openxr_controller.h
index eff81877..933b49b 100644
--- a/device/vr/openxr/openxr_controller.h
+++ b/device/vr/openxr/openxr_controller.h
@@ -24,6 +24,10 @@
 class OpenXrController {
  public:
   OpenXrController();
+
+  OpenXrController(const OpenXrController&) = delete;
+  OpenXrController& operator=(const OpenXrController&) = delete;
+
   ~OpenXrController();
 
   // The lifetime of OpenXRInputHelper is a superset of OpenXRController. Thus
@@ -166,8 +170,6 @@
 
   const OpenXRPathHelper* path_helper_;
   const OpenXrExtensionHelper* extension_helper_;
-
-  DISALLOW_COPY_AND_ASSIGN(OpenXrController);
 };
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_device.h b/device/vr/openxr/openxr_device.h
index e5e0e83..1662640d 100644
--- a/device/vr/openxr/openxr_device.h
+++ b/device/vr/openxr/openxr_device.h
@@ -29,6 +29,10 @@
       public mojom::XRCompositorHost {
  public:
   OpenXrDevice(VizContextProviderFactoryAsync context_provider_factory_async);
+
+  OpenXrDevice(const OpenXrDevice&) = delete;
+  OpenXrDevice& operator=(const OpenXrDevice&) = delete;
+
   ~OpenXrDevice() override;
 
   // VRDeviceBase
@@ -67,8 +71,6 @@
   mojom::XRRuntime::RequestSessionCallback request_session_callback_;
 
   base::WeakPtrFactory<OpenXrDevice> weak_ptr_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(OpenXrDevice);
 };
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_input_helper.h b/device/vr/openxr/openxr_input_helper.h
index 392e97a..8ea5bb2 100644
--- a/device/vr/openxr/openxr_input_helper.h
+++ b/device/vr/openxr/openxr_input_helper.h
@@ -29,6 +29,9 @@
 
   OpenXRInputHelper(XrSession session, XrSpace local_space);
 
+  OpenXRInputHelper(const OpenXRInputHelper&) = delete;
+  OpenXRInputHelper& operator=(const OpenXRInputHelper&) = delete;
+
   ~OpenXRInputHelper();
 
   std::vector<mojom::XRInputSourceStatePtr> GetInputState(
@@ -63,8 +66,6 @@
       controller_states_;
 
   std::unique_ptr<OpenXRPathHelper> path_helper_;
-
-  DISALLOW_COPY_AND_ASSIGN(OpenXRInputHelper);
 };
 
 }  // namespace device
diff --git a/device/vr/openxr/openxr_render_loop.h b/device/vr/openxr/openxr_render_loop.h
index a9659cd..d7f1d602 100644
--- a/device/vr/openxr/openxr_render_loop.h
+++ b/device/vr/openxr/openxr_render_loop.h
@@ -44,6 +44,10 @@
       VizContextProviderFactoryAsync context_provider_factory_async,
       XrInstance instance,
       const OpenXrExtensionHelper& extension_helper_);
+
+  OpenXrRenderLoop(const OpenXrRenderLoop&) = delete;
+  OpenXrRenderLoop& operator=(const OpenXrRenderLoop&) = delete;
+
   ~OpenXrRenderLoop() override;
 
  private:
@@ -146,8 +150,6 @@
 
   // This must be the last member
   base::WeakPtrFactory<OpenXrRenderLoop> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(OpenXrRenderLoop);
 };
 
 }  // namespace device
diff --git a/device/vr/orientation/orientation_device_provider.h b/device/vr/orientation/orientation_device_provider.h
index 70373c9..0a04097 100644
--- a/device/vr/orientation/orientation_device_provider.h
+++ b/device/vr/orientation/orientation_device_provider.h
@@ -23,6 +23,11 @@
  public:
   explicit VROrientationDeviceProvider(
       mojo::PendingRemote<device::mojom::SensorProvider> sensor_provider);
+
+  VROrientationDeviceProvider(const VROrientationDeviceProvider&) = delete;
+  VROrientationDeviceProvider& operator=(const VROrientationDeviceProvider&) =
+      delete;
+
   ~VROrientationDeviceProvider() override;
 
   void Initialize(
@@ -52,8 +57,6 @@
                                mojo::PendingRemote<mojom::XRRuntime>)>
       add_device_callback_;
   base::OnceClosure initialized_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(VROrientationDeviceProvider);
 };
 
 }  // namespace device
diff --git a/device/vr/test/fake_orientation_provider.h b/device/vr/test/fake_orientation_provider.h
index ebed3e3..0c288fad 100644
--- a/device/vr/test/fake_orientation_provider.h
+++ b/device/vr/test/fake_orientation_provider.h
@@ -15,6 +15,10 @@
 class DEVICE_VR_EXPORT FakeOrientationSensor : public mojom::Sensor {
  public:
   FakeOrientationSensor(mojo::PendingReceiver<mojom::Sensor> receiver);
+
+  FakeOrientationSensor(const FakeOrientationSensor&) = delete;
+  FakeOrientationSensor& operator=(const FakeOrientationSensor&) = delete;
+
   ~FakeOrientationSensor() override;
 
   void AddConfiguration(const PlatformSensorConfiguration& configuration,
@@ -30,8 +34,6 @@
 
  private:
   mojo::Receiver<mojom::Sensor> receiver_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeOrientationSensor);
 };
 
 }  // namespace device
diff --git a/device/vr/test/fake_vr_device.h b/device/vr/test/fake_vr_device.h
index 348d8ac..8afc00f 100644
--- a/device/vr/test/fake_vr_device.h
+++ b/device/vr/test/fake_vr_device.h
@@ -18,6 +18,10 @@
                                       public mojom::XRSessionController {
  public:
   explicit FakeVRDevice(mojom::XRDeviceId id);
+
+  FakeVRDevice(const FakeVRDevice&) = delete;
+  FakeVRDevice& operator=(const FakeVRDevice&) = delete;
+
   ~FakeVRDevice() override;
 
   void RequestSession(
@@ -41,8 +45,6 @@
                             uint32_t size);
 
   mojom::VRPosePtr pose_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeVRDevice);
 };
 
 }  // namespace device
diff --git a/device/vr/test/fake_vr_device_provider.h b/device/vr/test/fake_vr_device_provider.h
index 022e8d5..8eed663 100644
--- a/device/vr/test/fake_vr_device_provider.h
+++ b/device/vr/test/fake_vr_device_provider.h
@@ -18,6 +18,10 @@
 class DEVICE_VR_EXPORT FakeVRDeviceProvider : public VRDeviceProvider {
  public:
   FakeVRDeviceProvider();
+
+  FakeVRDeviceProvider(const FakeVRDeviceProvider&) = delete;
+  FakeVRDeviceProvider& operator=(const FakeVRDeviceProvider&) = delete;
+
   ~FakeVRDeviceProvider() override;
 
   // Adds devices to the provider with the given device, which will be
@@ -45,8 +49,6 @@
                                mojo::PendingRemote<mojom::XRRuntime>)>
       add_device_callback_;
   base::RepeatingCallback<void(mojom::XRDeviceId)> remove_device_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeVRDeviceProvider);
 };
 
 }  // namespace device
diff --git a/device/vr/test/fake_vr_service_client.h b/device/vr/test/fake_vr_service_client.h
index 68d8311..507397e 100644
--- a/device/vr/test/fake_vr_service_client.h
+++ b/device/vr/test/fake_vr_service_client.h
@@ -16,6 +16,10 @@
  public:
   explicit FakeVRServiceClient(
       mojo::PendingReceiver<mojom::VRServiceClient> receiver);
+
+  FakeVRServiceClient(const FakeVRServiceClient&) = delete;
+  FakeVRServiceClient& operator=(const FakeVRServiceClient&) = delete;
+
   ~FakeVRServiceClient() override;
 
   void OnDeviceChanged() override {}
@@ -25,8 +29,6 @@
  private:
   mojom::XRDeviceId last_device_id_ = static_cast<mojom::XRDeviceId>(0);
   mojo::Receiver<mojom::VRServiceClient> receiver_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeVRServiceClient);
 };
 
 }  // namespace device
diff --git a/device/vr/util/fps_meter.h b/device/vr/util/fps_meter.h
index bec9432..4f67e51 100644
--- a/device/vr/util/fps_meter.h
+++ b/device/vr/util/fps_meter.h
@@ -17,6 +17,10 @@
  public:
   FPSMeter();
   explicit FPSMeter(size_t window_size);
+
+  FPSMeter(const FPSMeter&) = delete;
+  FPSMeter& operator=(const FPSMeter&) = delete;
+
   ~FPSMeter();
 
   void AddFrame(const base::TimeTicks& time_stamp);
@@ -31,7 +35,6 @@
  private:
   SampleQueue frame_times_;
   base::TimeTicks last_time_stamp_;
-  DISALLOW_COPY_AND_ASSIGN(FPSMeter);
 };
 
 }  // namespace device
diff --git a/device/vr/util/gamepad_builder.h b/device/vr/util/gamepad_builder.h
index e9c0ad0..654dbed 100644
--- a/device/vr/util/gamepad_builder.h
+++ b/device/vr/util/gamepad_builder.h
@@ -32,6 +32,10 @@
   GamepadBuilder(const std::string& gamepad_id,
                  GamepadMapping mapping,
                  device::mojom::XRHandedness handedness);
+
+  GamepadBuilder(const GamepadBuilder&) = delete;
+  GamepadBuilder& operator=(const GamepadBuilder&) = delete;
+
   virtual ~GamepadBuilder();
 
   virtual bool IsValid() const;
@@ -51,9 +55,6 @@
   GamepadMapping GetMapping() const { return gamepad_.mapping; }
 
   Gamepad gamepad_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GamepadBuilder);
 };
 
 }  // namespace device
diff --git a/device/vr/util/sample_queue.h b/device/vr/util/sample_queue.h
index d5cb238..c4e3884 100644
--- a/device/vr/util/sample_queue.h
+++ b/device/vr/util/sample_queue.h
@@ -19,6 +19,10 @@
 class COMPONENT_EXPORT(DEVICE_VR_UTIL) SampleQueue {
  public:
   explicit SampleQueue(size_t window_size);
+
+  SampleQueue(const SampleQueue&) = delete;
+  SampleQueue& operator=(const SampleQueue&) = delete;
+
   ~SampleQueue();
 
   int64_t GetSum() const { return sum_; }
@@ -35,7 +39,6 @@
   size_t current_index_ = 0;
   size_t window_size_;
   std::vector<int64_t> samples_;
-  DISALLOW_COPY_AND_ASSIGN(SampleQueue);
 };
 
 }  // namespace device
diff --git a/device/vr/util/sliding_average.h b/device/vr/util/sliding_average.h
index 8eed606..f744d09 100644
--- a/device/vr/util/sliding_average.h
+++ b/device/vr/util/sliding_average.h
@@ -15,6 +15,10 @@
 class COMPONENT_EXPORT(DEVICE_VR_UTIL) SlidingAverage {
  public:
   explicit SlidingAverage(size_t window_size);
+
+  SlidingAverage(const SlidingAverage&) = delete;
+  SlidingAverage& operator=(const SlidingAverage&) = delete;
+
   ~SlidingAverage();
 
   void AddSample(int64_t value);
@@ -24,12 +28,15 @@
 
  private:
   SampleQueue values_;
-  DISALLOW_COPY_AND_ASSIGN(SlidingAverage);
 };
 
 class COMPONENT_EXPORT(DEVICE_VR_UTIL) SlidingTimeDeltaAverage {
  public:
   explicit SlidingTimeDeltaAverage(size_t window_size);
+
+  SlidingTimeDeltaAverage(const SlidingTimeDeltaAverage&) = delete;
+  SlidingTimeDeltaAverage& operator=(const SlidingTimeDeltaAverage&) = delete;
+
   virtual ~SlidingTimeDeltaAverage();
 
   virtual void AddSample(base::TimeDelta value);
@@ -41,7 +48,6 @@
 
  private:
   SlidingAverage sample_microseconds_;
-  DISALLOW_COPY_AND_ASSIGN(SlidingTimeDeltaAverage);
 };
 
 }  // namespace device
diff --git a/device/vr/util/xr_standard_gamepad_builder.h b/device/vr/util/xr_standard_gamepad_builder.h
index a677262..d1b04b5f 100644
--- a/device/vr/util/xr_standard_gamepad_builder.h
+++ b/device/vr/util/xr_standard_gamepad_builder.h
@@ -18,6 +18,10 @@
 class COMPONENT_EXPORT(DEVICE_VR_UTIL) XRStandardGamepadBuilder {
  public:
   XRStandardGamepadBuilder(device::mojom::XRHandedness handedness);
+
+  XRStandardGamepadBuilder(const XRStandardGamepadBuilder&) = delete;
+  XRStandardGamepadBuilder& operator=(const XRStandardGamepadBuilder&) = delete;
+
   virtual ~XRStandardGamepadBuilder();
   void SetPrimaryButton(const GamepadButton& button) {
     primary_button_ = button;
@@ -59,8 +63,6 @@
   bool has_optional_axes_ = false;
 
   device::mojom::XRHandedness handedness_;
-
-  DISALLOW_COPY_AND_ASSIGN(XRStandardGamepadBuilder);
 };
 
 }  // namespace device
diff --git a/device/vr/vr_device_base.h b/device/vr/vr_device_base.h
index 92ab03f..e78e651 100644
--- a/device/vr/vr_device_base.h
+++ b/device/vr/vr_device_base.h
@@ -26,6 +26,10 @@
 class COMPONENT_EXPORT(DEVICE_VR_BASE) VRDeviceBase : public mojom::XRRuntime {
  public:
   explicit VRDeviceBase(mojom::XRDeviceId id);
+
+  VRDeviceBase(const VRDeviceBase&) = delete;
+  VRDeviceBase& operator=(const VRDeviceBase&) = delete;
+
   ~VRDeviceBase() override;
 
   // XRRuntime implementation
@@ -81,8 +85,6 @@
   device::mojom::XRDeviceData device_data_;
 
   mojo::Receiver<mojom::XRRuntime> runtime_receiver_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(VRDeviceBase);
 };
 
 }  // namespace device
diff --git a/device/vr/vr_device_base_unittest.cc b/device/vr/vr_device_base_unittest.cc
index 39f847e..e492799c 100644
--- a/device/vr/vr_device_base_unittest.cc
+++ b/device/vr/vr_device_base_unittest.cc
@@ -25,6 +25,10 @@
 class VRDeviceBaseForTesting : public VRDeviceBase {
  public:
   VRDeviceBaseForTesting() : VRDeviceBase(mojom::XRDeviceId::FAKE_DEVICE_ID) {}
+
+  VRDeviceBaseForTesting(const VRDeviceBaseForTesting&) = delete;
+  VRDeviceBaseForTesting& operator=(const VRDeviceBaseForTesting&) = delete;
+
   ~VRDeviceBaseForTesting() override = default;
 
   void SetVRDisplayInfoForTest(mojom::VRDisplayInfoPtr display_info) {
@@ -34,10 +38,6 @@
   void RequestSession(
       mojom::XRRuntimeSessionOptionsPtr options,
       mojom::XRRuntime::RequestSessionCallback callback) override {}
-
- private:
-
-  DISALLOW_COPY_AND_ASSIGN(VRDeviceBaseForTesting);
 };
 
 class StubVRDeviceEventListener : public mojom::XRRuntimeEventListener {
@@ -66,6 +66,10 @@
 class VRDeviceTest : public testing::Test {
  public:
   VRDeviceTest() {}
+
+  VRDeviceTest(const VRDeviceTest&) = delete;
+  VRDeviceTest& operator=(const VRDeviceTest&) = delete;
+
   ~VRDeviceTest() override {}
 
  protected:
@@ -77,8 +81,6 @@
   }
 
   base::test::SingleThreadTaskEnvironment task_environment_;
-
-  DISALLOW_COPY_AND_ASSIGN(VRDeviceTest);
 };
 
 // Tests VRDevice class default behaviour when it dispatches "vrdevicechanged"
diff --git a/device/vr/windows/compositor_base.h b/device/vr/windows/compositor_base.h
index 54f0ed8..e597256 100644
--- a/device/vr/windows/compositor_base.h
+++ b/device/vr/windows/compositor_base.h
@@ -62,6 +62,10 @@
       base::OnceCallback<void(bool result, mojom::XRSessionPtr)>;
 
   XRCompositorCommon();
+
+  XRCompositorCommon(const XRCompositorCommon&) = delete;
+  XRCompositorCommon& operator=(const XRCompositorCommon&) = delete;
+
   ~XRCompositorCommon() override;
 
   // on_presentation_ended will be called when this the compositor stops
@@ -215,8 +219,6 @@
       mojom::XRVisibilityState::VISIBLE;
   mojom::VRStageParametersPtr current_stage_parameters_;
   uint32_t stage_parameters_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(XRCompositorCommon);
 };
 
 }  // namespace device
diff --git a/docs/updater/cup.md b/docs/updater/cup.md
index ffe1394f..473b97da 100644
--- a/docs/updater/cup.md
+++ b/docs/updater/cup.md
@@ -38,12 +38,10 @@
 
 For each request, the client assembles three components:
  1. The message body (the request body to be sent to the server).
- 2. A small random number to be used as a client nonce for freshness (at least
-    32 bits).
+ 2. A random value to be used as a nonce for freshness (at least 256 bits).
  3. A code to identify the public key the client will use to verify this
     request. The client converts the public key id and nonce to a string: the
-    public key is converted to decimal, and the nonce to hexadecimal (lowercase
-    a-f).
+    public key is converted to decimal, and the nonce to any url-safe encoding.
 
 The client stores the request body in a buffer, in UTF-8 format; it
 appends the keyid/nonce string to this buffer. It calculates a SHA-256 hash of
diff --git a/extensions/browser/extension_host.cc b/extensions/browser/extension_host.cc
index 3a5eaaa1..f32ea84 100644
--- a/extensions/browser/extension_host.cc
+++ b/extensions/browser/extension_host.cc
@@ -92,10 +92,6 @@
                              load_start_->Elapsed());
   }
 
-  content::NotificationService::current()->Notify(
-      extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
-      content::Source<BrowserContext>(browser_context_),
-      content::Details<ExtensionHost>(this));
   for (auto& observer : observer_list_)
     observer.OnExtensionHostDestroyed(this);
 
diff --git a/extensions/browser/notification_types.h b/extensions/browser/notification_types.h
index bee4284..03a1c7d 100644
--- a/extensions/browser/notification_types.h
+++ b/extensions/browser/notification_types.h
@@ -60,14 +60,6 @@
   // TODO(https://crbug.com/1174736): Remove.
   NOTIFICATION_EXTENSION_REMOVED,
 
-  // Sent before an ExtensionHost* is destroyed. The details are
-  // an ExtensionHost* and the source is a BrowserContext*.
-  //
-  // DEPRECATED: Use
-  // extensions::ExtensionHostObserver::OnExtensionHostDestroyed()
-  // TODO(https://crbug.com/1174738): Remove.
-  NOTIFICATION_EXTENSION_HOST_DESTROYED,
-
   // Sent by an ExtensionHost* when it has finished its initial page load,
   // including any external resources.
   // The details are an ExtensionHost* and the source is a BrowserContext*.
diff --git a/extensions/common/constants.cc b/extensions/common/constants.cc
index ad63f91..1388cb6 100644
--- a/extensions/common/constants.cc
+++ b/extensions/common/constants.cc
@@ -103,6 +103,8 @@
 const size_t kWebstoreSignaturesPublicKeySize =
     base::size(kWebstoreSignaturesPublicKey);
 
+const char kUpdateURLData[] = "update_url_data";
+
 const int kMainThreadId = 0;
 
 const char kMimeTypeJpeg[] = "image/jpeg";
diff --git a/extensions/common/constants.h b/extensions/common/constants.h
index 08d9160..d8343af 100644
--- a/extensions/common/constants.h
+++ b/extensions/common/constants.h
@@ -124,6 +124,9 @@
 extern const uint8_t kWebstoreSignaturesPublicKey[];
 extern const size_t kWebstoreSignaturesPublicKeySize;
 
+// A preference for storing the extension's update URL data.
+extern const char kUpdateURLData[];
+
 // Thread identifier for the main renderer thread (as opposed to a service
 // worker thread).
 // This is the default thread id used for extension event listeners registered
diff --git a/headless/lib/browser/headless_web_contents_impl.cc b/headless/lib/browser/headless_web_contents_impl.cc
index 09bb4b3e..a98d001 100644
--- a/headless/lib/browser/headless_web_contents_impl.cc
+++ b/headless/lib/browser/headless_web_contents_impl.cc
@@ -287,11 +287,18 @@
   child->begin_frame_control_enabled_ = parent->begin_frame_control_enabled_;
   child->InitializeWindow(child->web_contents_->GetContainerBounds());
 
-  // There may already be frames, so make sure they also have our services.
-  for (content::RenderFrameHost* frame_host :
-       child->web_contents_->GetAllFrames()) {
-    child->RenderFrameCreated(frame_host);
-  }
+  // There may already be frames and we may have missed the RenderFrameCreated
+  // callback so make sure they also have our services.
+  // We want to iterate all frame trees because RenderFrameCreated gets called
+  // for any RenderFrame created. base::Unretained is safe here because
+  // ForEachRenderFrameHost is synchronous.
+  child->web_contents_->ForEachRenderFrameHost(base::BindRepeating(
+      [](HeadlessWebContentsImpl* child,
+         content::RenderFrameHost* render_frame_host) {
+        if (render_frame_host->IsRenderFrameLive())
+          child->RenderFrameCreated(render_frame_host);
+      },
+      child.get()));
 
   return child;
 }
diff --git a/ios/chrome/browser/ios_chrome_main_parts.h b/ios/chrome/browser/ios_chrome_main_parts.h
index c29e26a..5090ad0 100644
--- a/ios/chrome/browser/ios_chrome_main_parts.h
+++ b/ios/chrome/browser/ios_chrome_main_parts.h
@@ -10,7 +10,6 @@
 #include "base/allocator/buildflags.h"
 #include "base/command_line.h"
 #include "base/macros.h"
-#include "base/metrics/field_trial.h"
 #include "ios/chrome/browser/ios_chrome_field_trials.h"
 #include "ios/web/public/init/web_main_parts.h"
 
@@ -52,10 +51,6 @@
 
   std::unique_ptr<ApplicationContextImpl> application_context_;
 
-  // Statistical testing infrastructure for the entire browser. NULL until
-  // SetUpMetricsAndFieldTrials is called.
-  std::unique_ptr<base::FieldTrialList> field_trial_list_;
-
   PrefService* local_state_;
 
   IOSChromeFieldTrials ios_field_trials_;
diff --git a/ios/chrome/browser/ios_chrome_main_parts.mm b/ios/chrome/browser/ios_chrome_main_parts.mm
index 042e4f0..66769ce 100644
--- a/ios/chrome/browser/ios_chrome_main_parts.mm
+++ b/ios/chrome/browser/ios_chrome_main_parts.mm
@@ -6,7 +6,6 @@
 
 #import <Foundation/Foundation.h>
 
-#include "base/base_switches.h"
 #include "base/check_op.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
@@ -367,11 +366,8 @@
 
   // Initialize FieldTrialList to support FieldTrials that use one-time
   // randomization.
-  // TODO(crbug.com/1249496): Remove |field_trial_list_| data member.
-  DCHECK(!field_trial_list_);
   application_context_->GetMetricsServicesManager()
       ->InstantiateFieldTrialList();
-  field_trial_list_.reset(base::FieldTrialList::GetInstance());
 
   std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
 
@@ -381,14 +377,8 @@
   std::vector<std::string> variation_ids =
       RegisterAllFeatureVariationParameters(&flags_storage, feature_list.get());
 
-  // On iOS, GPU benchmarking is not supported. So, pass in a dummy value for
-  // the name of the switch that enables gpu benchmarking.
-  // TODO(crbug.com/988603): This should also set up extra switch-dependent
-  // feature overrides.
   application_context_->GetVariationsService()->SetupFieldTrials(
-      "dummy-enable-gpu-benchmarking", switches::kEnableFeatures,
-      switches::kDisableFeatures, variation_ids,
-      std::vector<base::FeatureList::FeatureOverrideInfo>(),
+      variation_ids, std::vector<base::FeatureList::FeatureOverrideInfo>(),
       std::move(feature_list), &ios_field_trials_);
 }
 
diff --git a/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm b/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm
index 247fed3..93939a1 100644
--- a/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm
+++ b/ios/chrome/browser/metrics/ios_chrome_metrics_services_manager_client.mm
@@ -18,7 +18,6 @@
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state_manager.h"
 #include "ios/chrome/browser/chrome_paths.h"
-#include "ios/chrome/browser/chrome_switches.h"
 #import "ios/chrome/browser/main/browser.h"
 #import "ios/chrome/browser/main/browser_list.h"
 #import "ios/chrome/browser/main/browser_list_factory.h"
diff --git a/ios/chrome/browser/ui/history/history_ui_egtest.mm b/ios/chrome/browser/ui/history/history_ui_egtest.mm
index 3c4d33c..12dbbf0 100644
--- a/ios/chrome/browser/ui/history/history_ui_egtest.mm
+++ b/ios/chrome/browser/ui/history/history_ui_egtest.mm
@@ -575,6 +575,13 @@
 #pragma mark Multiwindow
 
 - (void)testHistorySyncInMultiwindow {
+// TODO(crbug.com/1252457): Test is flaky on iPad devices.
+#if !TARGET_IPHONE_SIMULATOR
+  if ([ChromeEarlGrey isIPadIdiom]) {
+    EARL_GREY_TEST_DISABLED(@"This test is flaky on iPad devices.");
+  }
+#endif
+
   if (![ChromeEarlGrey areMultipleWindowsSupported])
     EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
 
diff --git a/ios/third_party/native_closure_compiler/3pp/3pp.pb b/ios/third_party/native_closure_compiler/3pp/3pp.pb
new file mode 100644
index 0000000..e9a4e8a9
--- /dev/null
+++ b/ios/third_party/native_closure_compiler/3pp/3pp.pb
@@ -0,0 +1,20 @@
+# Copyright 2021 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.
+
+create {
+  source {
+    url {
+      download_url: "https://registry.npmjs.org/google-closure-compiler-osx/-/google-closure-compiler-osx-20210505.0.0.tgz"
+      version: "20210505.0.0"
+    }
+    unpack_archive: true
+  }
+  build {}
+}
+
+upload {
+  pkg_prefix: "chromium/third_party"
+  pkg_name_override: "native_closure_compiler_macos"
+  universal: true
+}
diff --git a/ios/third_party/native_closure_compiler/3pp/install.sh b/ios/third_party/native_closure_compiler/3pp/install.sh
new file mode 100755
index 0000000..7aef2ea
--- /dev/null
+++ b/ios/third_party/native_closure_compiler/3pp/install.sh
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copyright 2021 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.
+
+set -e
+set -x
+set -o pipefail
+
+PREFIX="$1"
+
+cp -a compiler "$PREFIX"
diff --git a/ios/third_party/native_closure_compiler/LICENSE b/ios/third_party/native_closure_compiler/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/ios/third_party/native_closure_compiler/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/ios/third_party/native_closure_compiler/OWNERS b/ios/third_party/native_closure_compiler/OWNERS
new file mode 100644
index 0000000..5100b76
--- /dev/null
+++ b/ios/third_party/native_closure_compiler/OWNERS
@@ -0,0 +1,2 @@
+michaeldo@chromium.org
+rohitrao@chromium.org
diff --git a/ios/third_party/native_closure_compiler/README.chromium b/ios/third_party/native_closure_compiler/README.chromium
new file mode 100644
index 0000000..06422d8
--- /dev/null
+++ b/ios/third_party/native_closure_compiler/README.chromium
@@ -0,0 +1,18 @@
+Name: Closure compiler NPM
+Short Name: closure-compiler-npm
+URL: https://github.com/google/closure-compiler-npm
+Version: 20210505.0.0
+Date: 2021/09/21 16:26
+License: Apache 2.0
+License File: LICENSE
+Security Critical: no
+
+Description:
+Check, compile, optimize and compress JavaScript with Closure-Compiler
+
+This repository tracks issues related to the publication to npmjs.org and
+associated plugins. Any bugs not related to the plugins themselves should be
+reported to the main repository.
+
+The compiler is distributed for multiple platforms. Each platform is its own npm
+package.
\ No newline at end of file
diff --git a/media/gpu/chromeos/platform_video_frame_utils.cc b/media/gpu/chromeos/platform_video_frame_utils.cc
index d501c0d1..b38b2e2 100644
--- a/media/gpu/chromeos/platform_video_frame_utils.cc
+++ b/media/gpu/chromeos/platform_video_frame_utils.cc
@@ -42,6 +42,14 @@
 
 namespace {
 
+gfx::GpuMemoryBufferId GetNextGpuMemoryBufferId() {
+  static base::NoDestructor<base::Lock> id_lock;
+  static int next_gpu_memory_buffer_id = 0;
+  base::AutoLock lock(*id_lock);
+  CHECK_LT(next_gpu_memory_buffer_id, std::numeric_limits<int>::max());
+  return gfx::GpuMemoryBufferId(next_gpu_memory_buffer_id++);
+}
+
 // GbmDeviceWrapper is a singleton that provides thread-safe access to a
 // ui::GbmDevice for the purposes of creating native BOs. The ui::GbmDevice is
 // initialized with the first non-vgem render node found that works starting at
@@ -82,13 +90,9 @@
     if (native_pixmap_handle.planes.empty())
       return gfx::GpuMemoryBufferHandle();
 
-    CHECK_LT(next_gpu_memory_buffer_id_, std::numeric_limits<int>::max());
-    const gfx::GpuMemoryBufferId gpu_memory_buffer_id(
-        next_gpu_memory_buffer_id_++);
-
     gfx::GpuMemoryBufferHandle gmb_handle;
     gmb_handle.type = gfx::GpuMemoryBufferType::NATIVE_PIXMAP;
-    gmb_handle.id = gpu_memory_buffer_id;
+    gmb_handle.id = GetNextGpuMemoryBufferId();
     gmb_handle.native_pixmap_handle = std::move(native_pixmap_handle);
     return gmb_handle;
   }
@@ -128,7 +132,6 @@
   base::Lock lock_;
   base::File render_node_file_ GUARDED_BY(lock_);
   std::unique_ptr<ui::GbmDevice> gbm_device_ GUARDED_BY(lock_);
-  int next_gpu_memory_buffer_id_ GUARDED_BY(lock_) = 0;
 };
 
 gfx::GpuMemoryBufferHandle AllocateGpuMemoryBufferHandle(
@@ -148,17 +151,8 @@
         *buffer_format, coded_size, buffer_usage);
   }
 
-  int gpu_memory_buffer_id;
-  {
-    static base::NoDestructor<base::Lock> id_lock;
-    static int next_gpu_memory_buffer_id = 0;
-    base::AutoLock lock(*id_lock);
-    CHECK_LT(next_gpu_memory_buffer_id, std::numeric_limits<int>::max());
-    gpu_memory_buffer_id = next_gpu_memory_buffer_id++;
-  }
-
   gmb_handle = factory->CreateGpuMemoryBuffer(
-      gfx::GpuMemoryBufferId(gpu_memory_buffer_id), coded_size,
+      GetNextGpuMemoryBufferId(), coded_size,
       /*framebuffer_size=*/GetRectSizeFromOrigin(visible_rect), *buffer_format,
       buffer_usage, gpu::kPlatformVideoFramePoolClientId,
       gfx::kNullAcceleratedWidget);
diff --git a/ppapi/host/instance_message_filter.h b/ppapi/host/instance_message_filter.h
index 83f7115..f258629 100644
--- a/ppapi/host/instance_message_filter.h
+++ b/ppapi/host/instance_message_filter.h
@@ -20,6 +20,10 @@
 class PPAPI_HOST_EXPORT InstanceMessageFilter {
  public:
   explicit InstanceMessageFilter(PpapiHost* host);
+
+  InstanceMessageFilter(const InstanceMessageFilter&) = delete;
+  InstanceMessageFilter& operator=(const InstanceMessageFilter&) = delete;
+
   virtual ~InstanceMessageFilter();
 
   // Processes an instance message from the plugin process. Returns true if the
@@ -31,8 +35,6 @@
 
  private:
   PpapiHost* host_;
-
-  DISALLOW_COPY_AND_ASSIGN(InstanceMessageFilter);
 };
 
 }  // namespace host
diff --git a/ppapi/host/message_filter_host.h b/ppapi/host/message_filter_host.h
index cfc52451..9538ed1e 100644
--- a/ppapi/host/message_filter_host.h
+++ b/ppapi/host/message_filter_host.h
@@ -27,10 +27,11 @@
                     PP_Instance instance,
                     PP_Resource resource,
                     const scoped_refptr<ResourceMessageFilter>& message_filter);
-  virtual ~MessageFilterHost();
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(MessageFilterHost);
+  MessageFilterHost(const MessageFilterHost&) = delete;
+  MessageFilterHost& operator=(const MessageFilterHost&) = delete;
+
+  virtual ~MessageFilterHost();
 };
 
 }  // namespace host
diff --git a/ppapi/host/ppapi_host.h b/ppapi/host/ppapi_host.h
index 99ef2b39..42559fa 100644
--- a/ppapi/host/ppapi_host.h
+++ b/ppapi/host/ppapi_host.h
@@ -44,6 +44,10 @@
   // (AddHostFactoryFilter) and instance messages (AddInstanceMessageFilter)
   // after construction.
   PpapiHost(IPC::Sender* sender, const PpapiPermissions& perms);
+
+  PpapiHost(const PpapiHost&) = delete;
+  PpapiHost& operator=(const PpapiHost&) = delete;
+
   ~PpapiHost() override;
 
   const PpapiPermissions& permissions() const { return permissions_; }
@@ -140,8 +144,6 @@
   typedef std::map<int, std::unique_ptr<ResourceHost>> PendingHostResourceMap;
   PendingHostResourceMap pending_resource_hosts_;
   int next_pending_resource_host_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(PpapiHost);
 };
 
 }  // namespace host
diff --git a/ppapi/host/resource_host.h b/ppapi/host/resource_host.h
index 1189d33a..83b5bf3b 100644
--- a/ppapi/host/resource_host.h
+++ b/ppapi/host/resource_host.h
@@ -31,6 +31,10 @@
 class PPAPI_HOST_EXPORT ResourceHost : public ResourceMessageHandler {
  public:
   ResourceHost(PpapiHost* host, PP_Instance instance, PP_Resource resource);
+
+  ResourceHost(const ResourceHost&) = delete;
+  ResourceHost& operator=(const ResourceHost&) = delete;
+
   ~ResourceHost() override;
 
   PpapiHost* host() { return host_; }
@@ -85,8 +89,6 @@
   // A vector of message filters which the host will forward incoming resource
   // messages to.
   std::vector<scoped_refptr<ResourceMessageFilter> > message_filters_;
-
-  DISALLOW_COPY_AND_ASSIGN(ResourceHost);
 };
 
 }  // namespace host
diff --git a/ppapi/host/resource_message_handler.h b/ppapi/host/resource_message_handler.h
index 8aeaf048..375fdecb 100644
--- a/ppapi/host/resource_message_handler.h
+++ b/ppapi/host/resource_message_handler.h
@@ -25,6 +25,10 @@
 class PPAPI_HOST_EXPORT ResourceMessageHandler {
  public:
   ResourceMessageHandler();
+
+  ResourceMessageHandler(const ResourceMessageHandler&) = delete;
+  ResourceMessageHandler& operator=(const ResourceMessageHandler&) = delete;
+
   virtual ~ResourceMessageHandler();
 
   // Called when this handler should handle a particular message. This should
@@ -63,9 +67,6 @@
   // The default implementation just returns PP_ERROR_NOTSUPPORTED.
   virtual int32_t OnResourceMessageReceived(const IPC::Message& msg,
                                             HostMessageContext* context);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ResourceMessageHandler);
 };
 
 }  // namespace host
diff --git a/ppapi/nacl_irt/manifest_service.h b/ppapi/nacl_irt/manifest_service.h
index cd2e233..c9251ca 100644
--- a/ppapi/nacl_irt/manifest_service.h
+++ b/ppapi/nacl_irt/manifest_service.h
@@ -29,6 +29,10 @@
   ManifestService(const IPC::ChannelHandle& handle,
                   scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
                   base::WaitableEvent* shutdown_event);
+
+  ManifestService(const ManifestService&) = delete;
+  ManifestService& operator=(const ManifestService&) = delete;
+
   ~ManifestService();
 
   void StartupInitializationComplete();
@@ -39,8 +43,6 @@
   scoped_refptr<IPC::SyncMessageFilter> filter_;
 
   base::Lock open_resource_lock_;
-
-  DISALLOW_COPY_AND_ASSIGN(ManifestService);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/proxy/audio_buffer_resource.h b/ppapi/proxy/audio_buffer_resource.h
index e447917..1e03dea 100644
--- a/ppapi/proxy/audio_buffer_resource.h
+++ b/ppapi/proxy/audio_buffer_resource.h
@@ -27,6 +27,9 @@
                      int32_t index,
                      MediaStreamBuffer* buffer);
 
+  AudioBufferResource(const AudioBufferResource&) = delete;
+  AudioBufferResource& operator=(const AudioBufferResource&) = delete;
+
   ~AudioBufferResource() override;
 
   // PluginResource overrides:
@@ -49,8 +52,6 @@
   int32_t index_;
 
   MediaStreamBuffer* buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioBufferResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/audio_input_resource.h b/ppapi/proxy/audio_input_resource.h
index 5c35ac7..84e5401a 100644
--- a/ppapi/proxy/audio_input_resource.h
+++ b/ppapi/proxy/audio_input_resource.h
@@ -35,6 +35,10 @@
                            public base::DelegateSimpleThread::Delegate {
  public:
   AudioInputResource(Connection connection, PP_Instance instance);
+
+  AudioInputResource(const AudioInputResource&) = delete;
+  AudioInputResource& operator=(const AudioInputResource&) = delete;
+
   ~AudioInputResource() override;
 
   // Resource overrides.
@@ -145,8 +149,6 @@
   // Internal buffer for client's integer audio data.
   int client_buffer_size_bytes_;
   std::unique_ptr<uint8_t[]> client_buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioInputResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/audio_output_resource.h b/ppapi/proxy/audio_output_resource.h
index 3dc96ff4..1b901c6a 100644
--- a/ppapi/proxy/audio_output_resource.h
+++ b/ppapi/proxy/audio_output_resource.h
@@ -36,6 +36,10 @@
                             public base::DelegateSimpleThread::Delegate {
  public:
   AudioOutputResource(Connection connection, PP_Instance instance);
+
+  AudioOutputResource(const AudioOutputResource&) = delete;
+  AudioOutputResource& operator=(const AudioOutputResource&) = delete;
+
   ~AudioOutputResource() override;
 
   // Resource overrides.
@@ -138,8 +142,6 @@
   // Internal buffer for client's integer audio data.
   int client_buffer_size_bytes_;
   std::unique_ptr<uint8_t[]> client_buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(AudioOutputResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/browser_font_singleton_resource.h b/ppapi/proxy/browser_font_singleton_resource.h
index bc332db..838d28c 100644
--- a/ppapi/proxy/browser_font_singleton_resource.h
+++ b/ppapi/proxy/browser_font_singleton_resource.h
@@ -20,6 +20,11 @@
       public thunk::PPB_BrowserFont_Singleton_API {
  public:
   BrowserFontSingletonResource(Connection connection, PP_Instance instance);
+
+  BrowserFontSingletonResource(const BrowserFontSingletonResource&) = delete;
+  BrowserFontSingletonResource& operator=(const BrowserFontSingletonResource&) =
+      delete;
+
   ~BrowserFontSingletonResource() override;
 
   // Resource override.
@@ -32,12 +37,9 @@
  private:
   // Lazily-filled-in list of font families.
   std::string families_;
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserFontSingletonResource);
 };
 
 }  // namespace proxy
 }  // namespace ppapi
 
 #endif  // PPAPI_PROXY_BROWSER_FONT_SINGLETON_RESOURCE_H_
-
diff --git a/ppapi/proxy/camera_capabilities_resource.h b/ppapi/proxy/camera_capabilities_resource.h
index ba92d4ae4..b491369 100644
--- a/ppapi/proxy/camera_capabilities_resource.h
+++ b/ppapi/proxy/camera_capabilities_resource.h
@@ -26,6 +26,10 @@
   CameraCapabilitiesResource(PP_Instance instance,
                              const std::vector<PP_VideoCaptureFormat>& formats);
 
+  CameraCapabilitiesResource(const CameraCapabilitiesResource&) = delete;
+  CameraCapabilitiesResource& operator=(const CameraCapabilitiesResource&) =
+      delete;
+
   ~CameraCapabilitiesResource() override;
 
   // Resource overrides.
@@ -39,8 +43,6 @@
  private:
   size_t num_video_capture_formats_;
   std::unique_ptr<PP_VideoCaptureFormat[]> video_capture_formats_;
-
-  DISALLOW_COPY_AND_ASSIGN(CameraCapabilitiesResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/camera_device_resource.h b/ppapi/proxy/camera_device_resource.h
index d6ff4b78..fa8df1a 100644
--- a/ppapi/proxy/camera_device_resource.h
+++ b/ppapi/proxy/camera_device_resource.h
@@ -26,6 +26,10 @@
       public thunk::PPB_CameraDevice_API {
  public:
   CameraDeviceResource(Connection connection, PP_Instance instance);
+
+  CameraDeviceResource(const CameraDeviceResource&) = delete;
+  CameraDeviceResource& operator=(const CameraDeviceResource&) = delete;
+
   ~CameraDeviceResource() override;
 
   // Resource overrides:
@@ -59,8 +63,6 @@
 
   scoped_refptr<TrackedCallback> get_capabilities_callback_;
   scoped_refptr<CameraCapabilitiesResource> camera_capabilities_;
-
-  DISALLOW_COPY_AND_ASSIGN(CameraDeviceResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/device_enumeration_resource_helper.h b/ppapi/proxy/device_enumeration_resource_helper.h
index 5c4fe72..9380ad25 100644
--- a/ppapi/proxy/device_enumeration_resource_helper.h
+++ b/ppapi/proxy/device_enumeration_resource_helper.h
@@ -38,6 +38,12 @@
  public:
   // |owner| must outlive this object.
   explicit DeviceEnumerationResourceHelper(PluginResource* owner);
+
+  DeviceEnumerationResourceHelper(const DeviceEnumerationResourceHelper&) =
+      delete;
+  DeviceEnumerationResourceHelper& operator=(
+      const DeviceEnumerationResourceHelper&) = delete;
+
   ~DeviceEnumerationResourceHelper();
 
   int32_t EnumerateDevices(const PP_ArrayOutput& output,
@@ -74,8 +80,6 @@
   std::unique_ptr<ThreadAwareCallback<PP_MonitorDeviceChangeCallback>>
       monitor_callback_;
   void* monitor_user_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeviceEnumerationResourceHelper);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/device_enumeration_resource_helper_unittest.cc b/ppapi/proxy/device_enumeration_resource_helper_unittest.cc
index d277ddc..3bfe5e8 100644
--- a/ppapi/proxy/device_enumeration_resource_helper_unittest.cc
+++ b/ppapi/proxy/device_enumeration_resource_helper_unittest.cc
@@ -74,6 +74,9 @@
         device_enumeration_(this) {
   }
 
+  TestResource(const TestResource&) = delete;
+  TestResource& operator=(const TestResource&) = delete;
+
   ~TestResource() override {}
 
   void OnReplyReceived(const ResourceMessageReplyParams& params,
@@ -88,14 +91,16 @@
 
  private:
   DeviceEnumerationResourceHelper device_enumeration_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestResource);
 };
 
 class TestCallback {
  public:
   TestCallback() : called_(false), result_(PP_ERROR_FAILED) {
   }
+
+  TestCallback(const TestCallback&) = delete;
+  TestCallback& operator=(const TestCallback&) = delete;
+
   ~TestCallback() {
     CHECK(called_);
   }
@@ -118,8 +123,6 @@
 
   bool called_;
   int32_t result_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestCallback);
 };
 
 class TestArrayOutput {
@@ -130,6 +133,9 @@
         resource_tracker_(resource_tracker) {
   }
 
+  TestArrayOutput(const TestArrayOutput&) = delete;
+  TestArrayOutput& operator=(const TestArrayOutput&) = delete;
+
   ~TestArrayOutput() {
     if (count_ > 0) {
       for (size_t i = 0; i < count_; ++i)
@@ -167,8 +173,6 @@
   PP_Resource* data_;
   uint32_t count_;
   PluginResourceTracker* resource_tracker_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestArrayOutput);
 };
 
 class TestMonitorDeviceChange {
@@ -179,6 +183,9 @@
         var_tracker_(var_tracker) {
   }
 
+  TestMonitorDeviceChange(const TestMonitorDeviceChange&) = delete;
+  TestMonitorDeviceChange& operator=(const TestMonitorDeviceChange&) = delete;
+
   ~TestMonitorDeviceChange() {}
 
   void SetExpectedResult(const std::vector<DeviceRefData>& expected) {
@@ -217,8 +224,6 @@
   bool same_as_expected_;
   std::vector<DeviceRefData> expected_;
   PluginVarTracker* var_tracker_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestMonitorDeviceChange);
 };
 
 }  // namespace
diff --git a/ppapi/proxy/dispatcher.h b/ppapi/proxy/dispatcher.h
index 468a5f9..e783f7cf 100644
--- a/ppapi/proxy/dispatcher.h
+++ b/ppapi/proxy/dispatcher.h
@@ -47,6 +47,9 @@
 //                                      |
 class PPAPI_PROXY_EXPORT Dispatcher : public ProxyChannel {
  public:
+  Dispatcher(const Dispatcher&) = delete;
+  Dispatcher& operator=(const Dispatcher&) = delete;
+
   ~Dispatcher() override;
 
   // Returns true if the dispatcher is on the plugin side, or false if it's the
@@ -97,8 +100,6 @@
   scoped_refptr<VarSerializationRules> serialization_rules_;
 
   PpapiPermissions permissions_;
-
-  DISALLOW_COPY_AND_ASSIGN(Dispatcher);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/file_chooser_resource.h b/ppapi/proxy/file_chooser_resource.h
index e3ec72d..5d4f332 100644
--- a/ppapi/proxy/file_chooser_resource.h
+++ b/ppapi/proxy/file_chooser_resource.h
@@ -32,6 +32,10 @@
                       PP_Instance instance,
                       PP_FileChooserMode_Dev mode,
                       const std::string& accept_types);
+
+  FileChooserResource(const FileChooserResource&) = delete;
+  FileChooserResource& operator=(const FileChooserResource&) = delete;
+
   ~FileChooserResource() override;
 
   // Resource overrides.
@@ -78,8 +82,6 @@
   base::queue<PP_Resource> file_queue_;
 
   scoped_refptr<TrackedCallback> callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileChooserResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/file_io_resource.h b/ppapi/proxy/file_io_resource.h
index f20f134..7f22505 100644
--- a/ppapi/proxy/file_io_resource.h
+++ b/ppapi/proxy/file_io_resource.h
@@ -33,6 +33,10 @@
       public thunk::PPB_FileIO_API {
  public:
   FileIOResource(Connection connection, PP_Instance instance);
+
+  FileIOResource(const FileIOResource&) = delete;
+  FileIOResource& operator=(const FileIOResource&) = delete;
+
   ~FileIOResource() override;
 
   // Resource overrides.
@@ -227,8 +231,6 @@
   int64_t append_mode_write_amount_;
   bool check_quota_;
   bool called_close_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileIOResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/file_ref_resource.h b/ppapi/proxy/file_ref_resource.h
index 1639655..38e4c172 100644
--- a/ppapi/proxy/file_ref_resource.h
+++ b/ppapi/proxy/file_ref_resource.h
@@ -32,6 +32,9 @@
                                    PP_Instance instance,
                                    const FileRefCreateInfo& info);
 
+  FileRefResource(const FileRefResource&) = delete;
+  FileRefResource& operator=(const FileRefResource&) = delete;
+
   ~FileRefResource() override;
 
   // Resource implementation.
@@ -93,8 +96,6 @@
   scoped_refptr<StringVar> name_var_;
   scoped_refptr<StringVar> path_var_;
   scoped_refptr<StringVar> absolute_path_var_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileRefResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/file_system_resource.h b/ppapi/proxy/file_system_resource.h
index ba53b56..8c112a73 100644
--- a/ppapi/proxy/file_system_resource.h
+++ b/ppapi/proxy/file_system_resource.h
@@ -44,6 +44,10 @@
                      int pending_renderer_id,
                      int pending_browser_id,
                      PP_FileSystemType type);
+
+  FileSystemResource(const FileSystemResource&) = delete;
+  FileSystemResource& operator=(const FileSystemResource&) = delete;
+
   ~FileSystemResource() override;
 
   // Resource overrides.
@@ -100,8 +104,6 @@
   base::queue<QuotaRequest> pending_quota_requests_;
   int64_t reserved_quota_;
   bool reserving_quota_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileSystemResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/flash_font_file_resource.h b/ppapi/proxy/flash_font_file_resource.h
index e547bee..7bf65c5 100644
--- a/ppapi/proxy/flash_font_file_resource.h
+++ b/ppapi/proxy/flash_font_file_resource.h
@@ -29,6 +29,10 @@
                         PP_Instance instance,
                         const PP_BrowserFont_Trusted_Description* description,
                         PP_PrivateFontCharset charset);
+
+  FlashFontFileResource(const FlashFontFileResource&) = delete;
+  FlashFontFileResource& operator=(const FlashFontFileResource&) = delete;
+
   ~FlashFontFileResource() override;
 
   // Resource overrides.
@@ -52,8 +56,6 @@
 
   SerializedFontDescription description_;
   const PP_PrivateFontCharset charset_;
-
-  DISALLOW_COPY_AND_ASSIGN(FlashFontFileResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/flash_fullscreen_resource.h b/ppapi/proxy/flash_fullscreen_resource.h
index 0c276a3c..a57b7a2b 100644
--- a/ppapi/proxy/flash_fullscreen_resource.h
+++ b/ppapi/proxy/flash_fullscreen_resource.h
@@ -19,6 +19,10 @@
  public:
   FlashFullscreenResource(Connection connection,
                           PP_Instance instance);
+
+  FlashFullscreenResource(const FlashFullscreenResource&) = delete;
+  FlashFullscreenResource& operator=(const FlashFullscreenResource&) = delete;
+
   ~FlashFullscreenResource() override;
 
   // Resource overrides.
@@ -32,8 +36,6 @@
 
  private:
   PP_Bool is_fullscreen_;
-
-  DISALLOW_COPY_AND_ASSIGN(FlashFullscreenResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/gamepad_resource.h b/ppapi/proxy/gamepad_resource.h
index 1df1a96..8e35763 100644
--- a/ppapi/proxy/gamepad_resource.h
+++ b/ppapi/proxy/gamepad_resource.h
@@ -28,6 +28,10 @@
         public thunk::PPB_Gamepad_API {
  public:
   GamepadResource(Connection connection, PP_Instance instance);
+
+  GamepadResource(const GamepadResource&) = delete;
+  GamepadResource& operator=(const GamepadResource&) = delete;
+
   ~GamepadResource() override;
 
   // Resource implementation.
@@ -44,8 +48,6 @@
 
   // Last data returned so we can use this in the event of a read failure.
   PP_GamepadsSampleData last_read_;
-
-  DISALLOW_COPY_AND_ASSIGN(GamepadResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/graphics_2d_resource.h b/ppapi/proxy/graphics_2d_resource.h
index ee9f1ab..d2b13053 100644
--- a/ppapi/proxy/graphics_2d_resource.h
+++ b/ppapi/proxy/graphics_2d_resource.h
@@ -27,6 +27,9 @@
                      const PP_Size& size,
                      PP_Bool is_always_opaque);
 
+  Graphics2DResource(const Graphics2DResource&) = delete;
+  Graphics2DResource& operator=(const Graphics2DResource&) = delete;
+
   ~Graphics2DResource() override;
 
   // Resource overrides.
@@ -55,8 +58,6 @@
   float scale_;
 
   scoped_refptr<TrackedCallback> current_flush_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(Graphics2DResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/host_dispatcher.h b/ppapi/proxy/host_dispatcher.h
index 4fd1bf57..5f4317e 100644
--- a/ppapi/proxy/host_dispatcher.h
+++ b/ppapi/proxy/host_dispatcher.h
@@ -165,12 +165,14 @@
 class ScopedModuleReference {
  public:
   explicit ScopedModuleReference(Dispatcher* dispatcher);
+
+  ScopedModuleReference(const ScopedModuleReference&) = delete;
+  ScopedModuleReference& operator=(const ScopedModuleReference&) = delete;
+
   ~ScopedModuleReference();
 
  private:
   HostDispatcher* dispatcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(ScopedModuleReference);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/host_resolver_private_resource.h b/ppapi/proxy/host_resolver_private_resource.h
index 14da867..149be1c 100644
--- a/ppapi/proxy/host_resolver_private_resource.h
+++ b/ppapi/proxy/host_resolver_private_resource.h
@@ -22,6 +22,11 @@
  public:
   HostResolverPrivateResource(Connection connection,
                               PP_Instance instance);
+
+  HostResolverPrivateResource(const HostResolverPrivateResource&) = delete;
+  HostResolverPrivateResource& operator=(const HostResolverPrivateResource&) =
+      delete;
+
   ~HostResolverPrivateResource() override;
 
   // PluginResource overrides.
@@ -36,9 +41,6 @@
   PP_Var GetCanonicalName() override;
   uint32_t GetSize() override;
   bool GetNetAddress(uint32_t index, PP_NetAddress_Private* address) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(HostResolverPrivateResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/host_resolver_resource.h b/ppapi/proxy/host_resolver_resource.h
index 034b741..de0b31f 100644
--- a/ppapi/proxy/host_resolver_resource.h
+++ b/ppapi/proxy/host_resolver_resource.h
@@ -21,6 +21,10 @@
       public thunk::PPB_HostResolver_API {
  public:
   HostResolverResource(Connection connection, PP_Instance instance);
+
+  HostResolverResource(const HostResolverResource&) = delete;
+  HostResolverResource& operator=(const HostResolverResource&) = delete;
+
   ~HostResolverResource() override;
 
   // PluginResource overrides.
@@ -34,9 +38,6 @@
   PP_Var GetCanonicalName() override;
   uint32_t GetNetAddressCount() override;
   PP_Resource GetNetAddress(uint32_t index) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(HostResolverResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/host_resolver_resource_base.h b/ppapi/proxy/host_resolver_resource_base.h
index 2147ba9..f5ecd48 100644
--- a/ppapi/proxy/host_resolver_resource_base.h
+++ b/ppapi/proxy/host_resolver_resource_base.h
@@ -35,6 +35,10 @@
   HostResolverResourceBase(Connection connection,
                            PP_Instance instance,
                            bool private_api);
+
+  HostResolverResourceBase(const HostResolverResourceBase&) = delete;
+  HostResolverResourceBase& operator=(const HostResolverResourceBase&) = delete;
+
   virtual ~HostResolverResourceBase();
 
   int32_t ResolveImpl(const char* host,
@@ -66,8 +70,6 @@
   bool allow_get_results_;
   std::string canonical_name_;
   std::vector<scoped_refptr<NetAddressResource> > net_address_list_;
-
-  DISALLOW_COPY_AND_ASSIGN(HostResolverResourceBase);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/host_var_serialization_rules.h b/ppapi/proxy/host_var_serialization_rules.h
index c5c93d2..7cc2b54 100644
--- a/ppapi/proxy/host_var_serialization_rules.h
+++ b/ppapi/proxy/host_var_serialization_rules.h
@@ -16,6 +16,11 @@
 class HostVarSerializationRules : public VarSerializationRules {
  public:
   HostVarSerializationRules();
+
+  HostVarSerializationRules(const HostVarSerializationRules&) = delete;
+  HostVarSerializationRules& operator=(const HostVarSerializationRules&) =
+      delete;
+
   ~HostVarSerializationRules();
 
   // VarSerialization implementation.
@@ -26,9 +31,6 @@
   virtual PP_Var BeginSendPassRef(const PP_Var& var);
   virtual void EndSendPassRef(const PP_Var& var);
   virtual void ReleaseObjectRef(const PP_Var& var);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(HostVarSerializationRules);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/interface_list.h b/ppapi/proxy/interface_list.h
index 070c6f3..d417305 100644
--- a/ppapi/proxy/interface_list.h
+++ b/ppapi/proxy/interface_list.h
@@ -22,6 +22,10 @@
 class PPAPI_PROXY_EXPORT InterfaceList {
  public:
   InterfaceList();
+
+  InterfaceList(const InterfaceList&) = delete;
+  InterfaceList& operator=(const InterfaceList&) = delete;
+
   ~InterfaceList();
 
   static InterfaceList* GetInstance();
@@ -102,12 +106,9 @@
   NameToInterfaceInfoMap name_to_plugin_info_;
 
   InterfaceProxy::Factory id_to_factory_[API_ID_COUNT];
-
-  DISALLOW_COPY_AND_ASSIGN(InterfaceList);
 };
 
 }  // namespace proxy
 }  // namespace ppapi
 
 #endif  // PPAPI_PROXY_INTERFACE_LIST_H_
-
diff --git a/ppapi/proxy/isolated_file_system_private_resource.h b/ppapi/proxy/isolated_file_system_private_resource.h
index a9e659f..757a7c6a 100644
--- a/ppapi/proxy/isolated_file_system_private_resource.h
+++ b/ppapi/proxy/isolated_file_system_private_resource.h
@@ -44,6 +44,12 @@
  public:
   IsolatedFileSystemPrivateResource(
       Connection connection, PP_Instance instance);
+
+  IsolatedFileSystemPrivateResource(const IsolatedFileSystemPrivateResource&) =
+      delete;
+  IsolatedFileSystemPrivateResource& operator=(
+      const IsolatedFileSystemPrivateResource&) = delete;
+
   ~IsolatedFileSystemPrivateResource() override;
 
   // Resource overrides.
@@ -62,8 +68,6 @@
                              scoped_refptr<TrackedCallback> callback,
                              const ResourceMessageReplyParams& params,
                              const std::string& fsid);
-
-  DISALLOW_COPY_AND_ASSIGN(IsolatedFileSystemPrivateResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/locking_resource_releaser.h b/ppapi/proxy/locking_resource_releaser.h
index d770df62f..291a087 100644
--- a/ppapi/proxy/locking_resource_releaser.h
+++ b/ppapi/proxy/locking_resource_releaser.h
@@ -23,6 +23,10 @@
   explicit LockingResourceReleaser(PP_Resource resource)
       : resource_(resource) {
   }
+
+  LockingResourceReleaser(const LockingResourceReleaser&) = delete;
+  LockingResourceReleaser& operator=(const LockingResourceReleaser&) = delete;
+
   ~LockingResourceReleaser() {
     ProxyAutoLock lock;
     PpapiGlobals::Get()->GetResourceTracker()->ReleaseResource(resource_);
@@ -32,8 +36,6 @@
 
  private:
   PP_Resource resource_;
-
-  DISALLOW_COPY_AND_ASSIGN(LockingResourceReleaser);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/media_stream_audio_track_resource.h b/ppapi/proxy/media_stream_audio_track_resource.h
index 3c25726..a27e6b8 100644
--- a/ppapi/proxy/media_stream_audio_track_resource.h
+++ b/ppapi/proxy/media_stream_audio_track_resource.h
@@ -30,6 +30,10 @@
                                 int pending_renderer_id,
                                 const std::string& id);
 
+  MediaStreamAudioTrackResource(const MediaStreamAudioTrackResource&) = delete;
+  MediaStreamAudioTrackResource& operator=(
+      const MediaStreamAudioTrackResource&) = delete;
+
   ~MediaStreamAudioTrackResource() override;
 
   // Resource overrides:
@@ -68,8 +72,6 @@
   scoped_refptr<TrackedCallback> configure_callback_;
 
   scoped_refptr<TrackedCallback> get_buffer_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaStreamAudioTrackResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/media_stream_video_track_resource.h b/ppapi/proxy/media_stream_video_track_resource.h
index 1b18cfa..a7bb5fe 100644
--- a/ppapi/proxy/media_stream_video_track_resource.h
+++ b/ppapi/proxy/media_stream_video_track_resource.h
@@ -31,6 +31,10 @@
 
   MediaStreamVideoTrackResource(Connection connection, PP_Instance instance);
 
+  MediaStreamVideoTrackResource(const MediaStreamVideoTrackResource&) = delete;
+  MediaStreamVideoTrackResource& operator=(
+      const MediaStreamVideoTrackResource&) = delete;
+
   ~MediaStreamVideoTrackResource() override;
 
   // Resource overrides:
@@ -72,8 +76,6 @@
   scoped_refptr<TrackedCallback> get_frame_callback_;
 
   scoped_refptr<TrackedCallback> configure_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaStreamVideoTrackResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/message_handler.h b/ppapi/proxy/message_handler.h
index 363312e..aed4123 100644
--- a/ppapi/proxy/message_handler.h
+++ b/ppapi/proxy/message_handler.h
@@ -51,6 +51,10 @@
       void* user_data,
       PP_Resource message_loop,
       int32_t* error);
+
+  MessageHandler(const MessageHandler&) = delete;
+  MessageHandler& operator=(const MessageHandler&) = delete;
+
   ~MessageHandler();
 
   bool LoopIsValid() const;
@@ -68,8 +72,6 @@
   const PPP_MessageHandler_0_2* handler_if_;
   void* user_data_;
   scoped_refptr<MessageLoopResource> message_loop_;
-
-  DISALLOW_COPY_AND_ASSIGN(MessageHandler);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/mock_resource.h b/ppapi/proxy/mock_resource.h
index ed894bda..5b024e5 100644
--- a/ppapi/proxy/mock_resource.h
+++ b/ppapi/proxy/mock_resource.h
@@ -15,10 +15,11 @@
 class MockResource : public ppapi::Resource {
  public:
   MockResource(const ppapi::HostResource& resource);
-  virtual ~MockResource();
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(MockResource);
+  MockResource(const MockResource&) = delete;
+  MockResource& operator=(const MockResource&) = delete;
+
+  virtual ~MockResource();
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/nacl_message_scanner.h b/ppapi/proxy/nacl_message_scanner.h
index 9f9d73a..0681360 100644
--- a/ppapi/proxy/nacl_message_scanner.h
+++ b/ppapi/proxy/nacl_message_scanner.h
@@ -28,6 +28,10 @@
 class PPAPI_PROXY_EXPORT NaClMessageScanner {
  public:
   NaClMessageScanner();
+
+  NaClMessageScanner(const NaClMessageScanner&) = delete;
+  NaClMessageScanner& operator=(const NaClMessageScanner&) = delete;
+
   ~NaClMessageScanner();
 
   // Scans the message for items that require special handling. Copies any
@@ -58,6 +62,10 @@
   class PPAPI_PROXY_EXPORT FileSystem {
    public:
     FileSystem();
+
+    FileSystem(const FileSystem&) = delete;
+    FileSystem& operator=(const FileSystem&) = delete;
+
     ~FileSystem();
 
     int64_t reserved_quota() const { return reserved_quota_; }
@@ -71,14 +79,16 @@
     // Acquire the lock to modify this field, since it may be used on multiple
     // threads.
     int64_t reserved_quota_;
-
-    DISALLOW_COPY_AND_ASSIGN(FileSystem);
   };
 
   // FileIO information for quota auditing.
   class PPAPI_PROXY_EXPORT FileIO {
    public:
     FileIO(FileSystem* file_system, int64_t max_written_offset);
+
+    FileIO(const FileIO&) = delete;
+    FileIO& operator=(const FileIO&) = delete;
+
     ~FileIO();
 
     int64_t max_written_offset() { return max_written_offset_; }
@@ -98,8 +108,6 @@
     // when the file is opened and modified by a NaClDescQuotaInterface when the
     // plugin writes to greater maximum offsets.
     int64_t max_written_offset_;
-
-    DISALLOW_COPY_AND_ASSIGN(FileIO);
   };
 
   FileIO* GetFile(PP_Resource file_io);
@@ -117,8 +125,6 @@
   FileSystemMap file_systems_;
   typedef std::map<int32_t, FileIO*> FileIOMap;
   FileIOMap files_;
-
-  DISALLOW_COPY_AND_ASSIGN(NaClMessageScanner);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/net_address_resource.h b/ppapi/proxy/net_address_resource.h
index f5448966..9eebe23 100644
--- a/ppapi/proxy/net_address_resource.h
+++ b/ppapi/proxy/net_address_resource.h
@@ -28,6 +28,9 @@
                      PP_Instance instance,
                      const PP_NetAddress_Private& private_addr);
 
+  NetAddressResource(const NetAddressResource&) = delete;
+  NetAddressResource& operator=(const NetAddressResource&) = delete;
+
   ~NetAddressResource() override;
 
   // PluginResource implementation.
@@ -44,8 +47,6 @@
   // TODO(yzshen): Refactor the code so that PPB_NetAddress resource doesn't
   // use PP_NetAddress_Private as storage type.
   PP_NetAddress_Private address_;
-
-  DISALLOW_COPY_AND_ASSIGN(NetAddressResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/network_list_resource.h b/ppapi/proxy/network_list_resource.h
index 9a497df..a88b184 100644
--- a/ppapi/proxy/network_list_resource.h
+++ b/ppapi/proxy/network_list_resource.h
@@ -24,6 +24,10 @@
  public:
   NetworkListResource(PP_Instance instance,
                       const SerializedNetworkList& list);
+
+  NetworkListResource(const NetworkListResource&) = delete;
+  NetworkListResource& operator=(const NetworkListResource&) = delete;
+
   ~NetworkListResource() override;
 
   // Resource override.
@@ -40,8 +44,6 @@
 
  private:
   SerializedNetworkList list_;
-
-  DISALLOW_COPY_AND_ASSIGN(NetworkListResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/network_monitor_resource.h b/ppapi/proxy/network_monitor_resource.h
index 9d23a4d..6a442a04 100644
--- a/ppapi/proxy/network_monitor_resource.h
+++ b/ppapi/proxy/network_monitor_resource.h
@@ -21,6 +21,10 @@
  public:
   explicit NetworkMonitorResource(Connection connection,
                                   PP_Instance instance);
+
+  NetworkMonitorResource(const NetworkMonitorResource&) = delete;
+  NetworkMonitorResource& operator=(const NetworkMonitorResource&) = delete;
+
   ~NetworkMonitorResource() override;
 
   // PluginResource overrides.
@@ -45,8 +49,6 @@
   // Parameters passed to UpdateNetworkList().
   PP_Resource* network_list_;
   scoped_refptr<TrackedCallback> update_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(NetworkMonitorResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/network_proxy_resource.h b/ppapi/proxy/network_proxy_resource.h
index 646e046..41bca8b0f 100644
--- a/ppapi/proxy/network_proxy_resource.h
+++ b/ppapi/proxy/network_proxy_resource.h
@@ -21,6 +21,10 @@
         public thunk::PPB_NetworkProxy_API {
  public:
   NetworkProxyResource(Connection connection, PP_Instance instance);
+
+  NetworkProxyResource(const NetworkProxyResource&) = delete;
+  NetworkProxyResource& operator=(const NetworkProxyResource&) = delete;
+
   ~NetworkProxyResource() override;
 
  private:
@@ -38,8 +42,6 @@
                                       scoped_refptr<TrackedCallback> callback,
                                       const ResourceMessageReplyParams& params,
                                       const std::string& proxy_string);
-
-  DISALLOW_COPY_AND_ASSIGN(NetworkProxyResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/pdf_resource.h b/ppapi/proxy/pdf_resource.h
index 124872c3..28763e0 100644
--- a/ppapi/proxy/pdf_resource.h
+++ b/ppapi/proxy/pdf_resource.h
@@ -24,6 +24,10 @@
       public thunk::PPB_PDF_API {
  public:
   PDFResource(Connection connection, PP_Instance instance);
+
+  PDFResource(const PDFResource&) = delete;
+  PDFResource& operator=(const PDFResource&) = delete;
+
   ~PDFResource() override;
 
   // For unittesting with a given locale.
@@ -74,8 +78,6 @@
 
  private:
   std::string locale_;
-
-  DISALLOW_COPY_AND_ASSIGN(PDFResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/plugin_array_buffer_var.h b/ppapi/proxy/plugin_array_buffer_var.h
index 0f7a5022..05c906f 100644
--- a/ppapi/proxy/plugin_array_buffer_var.h
+++ b/ppapi/proxy/plugin_array_buffer_var.h
@@ -24,6 +24,10 @@
   explicit PluginArrayBufferVar(uint32_t size_in_bytes);
   PluginArrayBufferVar(uint32_t size_in_bytes,
                        base::UnsafeSharedMemoryRegion plugin_handle);
+
+  PluginArrayBufferVar(const PluginArrayBufferVar&) = delete;
+  PluginArrayBufferVar& operator=(const PluginArrayBufferVar&) = delete;
+
   ~PluginArrayBufferVar() override;
 
   // ArrayBufferVar implementation.
@@ -42,8 +46,6 @@
   base::UnsafeSharedMemoryRegion plugin_handle_;
   base::WritableSharedMemoryMapping shmem_;
   uint32_t size_in_bytes_;
-
-  DISALLOW_COPY_AND_ASSIGN(PluginArrayBufferVar);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/proxy/plugin_dispatcher.h b/ppapi/proxy/plugin_dispatcher.h
index 2586b938..1c8f5b4 100644
--- a/ppapi/proxy/plugin_dispatcher.h
+++ b/ppapi/proxy/plugin_dispatcher.h
@@ -115,6 +115,10 @@
    public:
     Sender(base::WeakPtr<PluginDispatcher> plugin_dispatcher,
            scoped_refptr<IPC::SyncMessageFilter> sync_filter);
+
+    Sender(const Sender&) = delete;
+    Sender& operator=(const Sender&) = delete;
+
     ~Sender() override;
 
     bool SendMessage(IPC::Message* msg);
@@ -125,8 +129,6 @@
    private:
     base::WeakPtr<PluginDispatcher> plugin_dispatcher_;
     scoped_refptr<IPC::SyncMessageFilter> sync_filter_;
-
-    DISALLOW_COPY_AND_ASSIGN(Sender);
   };
 
   // Constructor for the plugin side. The init and shutdown functions will be
diff --git a/ppapi/proxy/plugin_globals.cc b/ppapi/proxy/plugin_globals.cc
index b0a6d9e..2719338 100644
--- a/ppapi/proxy/plugin_globals.cc
+++ b/ppapi/proxy/plugin_globals.cc
@@ -37,6 +37,9 @@
       : underlying_sender_(underlying_sender) {
   }
 
+  BrowserSender(const BrowserSender&) = delete;
+  BrowserSender& operator=(const BrowserSender&) = delete;
+
   ~BrowserSender() override {}
 
   // IPC::Sender implementation.
@@ -53,8 +56,6 @@
  private:
   // Non-owning pointer.
   IPC::Sender* underlying_sender_;
-
-  DISALLOW_COPY_AND_ASSIGN(BrowserSender);
 };
 
 PluginGlobals* PluginGlobals::plugin_globals_ = NULL;
diff --git a/ppapi/proxy/plugin_globals.h b/ppapi/proxy/plugin_globals.h
index ac39314..404566a 100644
--- a/ppapi/proxy/plugin_globals.h
+++ b/ppapi/proxy/plugin_globals.h
@@ -50,6 +50,10 @@
   PluginGlobals(
       PpapiGlobals::PerThreadForTest,
       const scoped_refptr<base::SingleThreadTaskRunner>& ipc_task_runner);
+
+  PluginGlobals(const PluginGlobals&) = delete;
+  PluginGlobals& operator=(const PluginGlobals&) = delete;
+
   ~PluginGlobals() override;
 
   // Getter for the global singleton. Generally, you should use
@@ -186,8 +190,6 @@
 
   // Member variables should appear before the WeakPtrFactory, see weak_ptr.h.
   base::WeakPtrFactory<PluginGlobals> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(PluginGlobals);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/plugin_resource.h b/ppapi/proxy/plugin_resource.h
index 19c725f0..fddb5c4a 100644
--- a/ppapi/proxy/plugin_resource.h
+++ b/ppapi/proxy/plugin_resource.h
@@ -38,6 +38,10 @@
   };
 
   PluginResource(Connection connection, PP_Instance instance);
+
+  PluginResource(const PluginResource&) = delete;
+  PluginResource& operator=(const PluginResource&) = delete;
+
   ~PluginResource() override;
 
   // Returns true if we've previously sent a create message to the browser
@@ -183,8 +187,6 @@
   CallbackMap callbacks_;
 
   scoped_refptr<ResourceReplyThreadRegistrar> resource_reply_thread_registrar_;
-
-  DISALLOW_COPY_AND_ASSIGN(PluginResource);
 };
 
 template <typename ReplyMsgClass, typename CallbackType>
diff --git a/ppapi/proxy/plugin_resource_tracker.h b/ppapi/proxy/plugin_resource_tracker.h
index c9fe858..743496ef 100644
--- a/ppapi/proxy/plugin_resource_tracker.h
+++ b/ppapi/proxy/plugin_resource_tracker.h
@@ -31,6 +31,10 @@
 class PPAPI_PROXY_EXPORT PluginResourceTracker : public ResourceTracker {
  public:
   PluginResourceTracker();
+
+  PluginResourceTracker(const PluginResourceTracker&) = delete;
+  PluginResourceTracker& operator=(const PluginResourceTracker&) = delete;
+
   ~PluginResourceTracker() override;
 
   // Given a host resource, maps it to an existing plugin resource ID if it
@@ -62,8 +66,6 @@
   HostResourceMap host_resource_map_;
 
   std::unordered_set<PP_Resource> abandoned_resources_;
-
-  DISALLOW_COPY_AND_ASSIGN(PluginResourceTracker);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/plugin_var_serialization_rules.h b/ppapi/proxy/plugin_var_serialization_rules.h
index 1f11669..511227c 100644
--- a/ppapi/proxy/plugin_var_serialization_rules.h
+++ b/ppapi/proxy/plugin_var_serialization_rules.h
@@ -22,6 +22,11 @@
   // handle object refcounting and string conversion.
   explicit PluginVarSerializationRules(
       const base::WeakPtr<PluginDispatcher>& dispatcher);
+
+  PluginVarSerializationRules(const PluginVarSerializationRules&) = delete;
+  PluginVarSerializationRules& operator=(const PluginVarSerializationRules&) =
+      delete;
+
   ~PluginVarSerializationRules();
 
   // VarSerialization implementation.
@@ -44,8 +49,6 @@
   // If that happens, we may leak references to object vars. Considering that
   // scripting has been deprecated, this may not be a big issue.
   base::WeakPtr<PluginDispatcher> dispatcher_;
-
-  DISALLOW_COPY_AND_ASSIGN(PluginVarSerializationRules);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h
index 37336c0..031a2ca 100644
--- a/ppapi/proxy/plugin_var_tracker.h
+++ b/ppapi/proxy/plugin_var_tracker.h
@@ -35,6 +35,10 @@
 class PPAPI_PROXY_EXPORT PluginVarTracker : public VarTracker {
  public:
   PluginVarTracker();
+
+  PluginVarTracker(const PluginVarTracker&) = delete;
+  PluginVarTracker& operator=(const PluginVarTracker&) = delete;
+
   ~PluginVarTracker() override;
 
   // Manages tracking for receiving a VARTYPE_OBJECT from the remote side
@@ -203,8 +207,6 @@
   typedef std::map<void*, PluginImplementedVar>
       UserDataToPluginImplementedVarMap;
   UserDataToPluginImplementedVarMap user_data_to_plugin_;
-
-  DISALLOW_COPY_AND_ASSIGN(PluginVarTracker);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppapi_command_buffer_proxy.h b/ppapi/proxy/ppapi_command_buffer_proxy.h
index d3d2138..a7d3434 100644
--- a/ppapi/proxy/ppapi_command_buffer_proxy.h
+++ b/ppapi/proxy/ppapi_command_buffer_proxy.h
@@ -38,6 +38,10 @@
                           const gpu::Capabilities& capabilities,
                           SerializedHandle shared_state,
                           gpu::CommandBufferId command_buffer_id);
+
+  PpapiCommandBufferProxy(const PpapiCommandBufferProxy&) = delete;
+  PpapiCommandBufferProxy& operator=(const PpapiCommandBufferProxy&) = delete;
+
   ~PpapiCommandBufferProxy() override;
 
   // gpu::CommandBuffer implementation:
@@ -107,8 +111,6 @@
   uint64_t pending_fence_sync_release_;
   uint64_t flushed_fence_sync_release_;
   uint64_t validated_fence_sync_release_;
-
-  DISALLOW_COPY_AND_ASSIGN(PpapiCommandBufferProxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppapi_proxy_test.h b/ppapi/proxy/ppapi_proxy_test.h
index d5efbd50..2c90349e 100644
--- a/ppapi/proxy/ppapi_proxy_test.h
+++ b/ppapi/proxy/ppapi_proxy_test.h
@@ -127,6 +127,10 @@
                              public PluginProxyDelegate {
    public:
     PluginDelegateMock() : ipc_task_runner_(NULL), shutdown_event_() {}
+
+    PluginDelegateMock(const PluginDelegateMock&) = delete;
+    PluginDelegateMock& operator=(const PluginDelegateMock&) = delete;
+
     ~PluginDelegateMock() override {}
 
     void Init(base::SingleThreadTaskRunner* ipc_task_runner,
@@ -173,8 +177,6 @@
     base::WaitableEvent* shutdown_event_;  // Weak
     std::set<PP_Instance> instance_id_set_;
     IPC::Sender* browser_sender_;
-
-    DISALLOW_COPY_AND_ASSIGN(PluginDelegateMock);
   };
 
  private:
@@ -276,6 +278,10 @@
   class DelegateMock : public ProxyChannel::Delegate {
    public:
     DelegateMock() : ipc_task_runner_(NULL), shutdown_event_(NULL) {}
+
+    DelegateMock(const DelegateMock&) = delete;
+    DelegateMock& operator=(const DelegateMock&) = delete;
+
     ~DelegateMock() override {}
 
     void Init(base::SingleThreadTaskRunner* ipc_task_runner,
@@ -301,8 +307,6 @@
    private:
     base::SingleThreadTaskRunner* ipc_task_runner_;  // Weak
     base::WaitableEvent* shutdown_event_;  // Weak
-
-    DISALLOW_COPY_AND_ASSIGN(DelegateMock);
   };
 
  private:
diff --git a/ppapi/proxy/ppb_audio_proxy.cc b/ppapi/proxy/ppb_audio_proxy.cc
index b8500f1..f0ee2d4 100644
--- a/ppapi/proxy/ppb_audio_proxy.cc
+++ b/ppapi/proxy/ppb_audio_proxy.cc
@@ -40,6 +40,10 @@
         PP_Resource config_id,
         const AudioCallbackCombined& callback,
         void* user_data);
+
+  Audio(const Audio&) = delete;
+  Audio& operator=(const Audio&) = delete;
+
   ~Audio() override;
 
   // Resource overrides.
@@ -58,8 +62,6 @@
   // Owning reference to the current config object. This isn't actually used,
   // we just dish it out as requested by the plugin.
   PP_Resource config_;
-
-  DISALLOW_COPY_AND_ASSIGN(Audio);
 };
 
 Audio::Audio(const HostResource& audio_id,
diff --git a/ppapi/proxy/ppb_audio_proxy.h b/ppapi/proxy/ppb_audio_proxy.h
index 6d50479..04742bc 100644
--- a/ppapi/proxy/ppb_audio_proxy.h
+++ b/ppapi/proxy/ppb_audio_proxy.h
@@ -31,6 +31,10 @@
 class PPB_Audio_Proxy : public InterfaceProxy {
  public:
   explicit PPB_Audio_Proxy(Dispatcher* dispatcher);
+
+  PPB_Audio_Proxy(const PPB_Audio_Proxy&) = delete;
+  PPB_Audio_Proxy& operator=(const PPB_Audio_Proxy&) = delete;
+
   ~PPB_Audio_Proxy() override;
 
   // Creates an Audio object in the plugin process.
@@ -77,8 +81,6 @@
       base::UnsafeSharedMemoryRegion* foreign_shared_memory_region);
 
   ProxyCompletionCallbackFactory<PPB_Audio_Proxy> callback_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_Audio_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppb_buffer_proxy.h b/ppapi/proxy/ppb_buffer_proxy.h
index f79497e..78696593 100644
--- a/ppapi/proxy/ppb_buffer_proxy.h
+++ b/ppapi/proxy/ppb_buffer_proxy.h
@@ -27,6 +27,10 @@
  public:
   Buffer(const HostResource& resource,
          base::UnsafeSharedMemoryRegion shm_handle);
+
+  Buffer(const Buffer&) = delete;
+  Buffer& operator=(const Buffer&) = delete;
+
   ~Buffer() override;
 
   // Resource overrides.
@@ -45,8 +49,6 @@
   base::UnsafeSharedMemoryRegion shm_;
   base::WritableSharedMemoryMapping mapping_;
   int map_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(Buffer);
 };
 
 class PPB_Buffer_Proxy : public InterfaceProxy {
diff --git a/ppapi/proxy/ppb_graphics_3d_proxy.h b/ppapi/proxy/ppb_graphics_3d_proxy.h
index 8d2f636..20f50843 100644
--- a/ppapi/proxy/ppb_graphics_3d_proxy.h
+++ b/ppapi/proxy/ppb_graphics_3d_proxy.h
@@ -40,6 +40,10 @@
   Graphics3D(const HostResource& resource,
              const gfx::Size& size,
              const bool single_buffer);
+
+  Graphics3D(const Graphics3D&) = delete;
+  Graphics3D& operator=(const Graphics3D&) = delete;
+
   ~Graphics3D() override;
 
   bool Init(gpu::gles2::GLES2Implementation* share_gles2,
@@ -73,13 +77,15 @@
 
   uint64_t swap_id_ = 0;
   bool single_buffer = false;
-
-  DISALLOW_COPY_AND_ASSIGN(Graphics3D);
 };
 
 class PPB_Graphics3D_Proxy : public InterfaceProxy {
  public:
   explicit PPB_Graphics3D_Proxy(Dispatcher* dispatcher);
+
+  PPB_Graphics3D_Proxy(const PPB_Graphics3D_Proxy&) = delete;
+  PPB_Graphics3D_Proxy& operator=(const PPB_Graphics3D_Proxy&) = delete;
+
   ~PPB_Graphics3D_Proxy();
 
   static PP_Resource CreateProxyResource(
@@ -132,8 +138,6 @@
                                   const HostResource& context);
 
   ProxyCompletionCallbackFactory<PPB_Graphics3D_Proxy> callback_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_Graphics3D_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppb_image_data_proxy.cc b/ppapi/proxy/ppb_image_data_proxy.cc
index e74b776..b49b57b 100644
--- a/ppapi/proxy/ppb_image_data_proxy.cc
+++ b/ppapi/proxy/ppb_image_data_proxy.cc
@@ -223,6 +223,10 @@
 class ImageDataCache {
  public:
   ImageDataCache() {}
+
+  ImageDataCache(const ImageDataCache&) = delete;
+  ImageDataCache& operator=(const ImageDataCache&) = delete;
+
   ~ImageDataCache() {}
 
   static ImageDataCache* GetInstance();
@@ -257,8 +261,6 @@
   // this will never happen and this factory is unnecessary. However, it's
   // probably better not to make assumptions about the lifetime of this class.
   base::WeakPtrFactory<ImageDataCache> weak_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(ImageDataCache);
 };
 
 // static
diff --git a/ppapi/proxy/ppb_image_data_proxy.h b/ppapi/proxy/ppb_image_data_proxy.h
index afdbf49..db533b2 100644
--- a/ppapi/proxy/ppb_image_data_proxy.h
+++ b/ppapi/proxy/ppb_image_data_proxy.h
@@ -46,6 +46,9 @@
                                      public ppapi::thunk::PPB_ImageData_API,
                                      public ppapi::PPB_ImageData_Shared {
  public:
+  ImageData(const ImageData&) = delete;
+  ImageData& operator=(const ImageData&) = delete;
+
   ~ImageData() override;
 
   // Resource overrides.
@@ -76,8 +79,6 @@
 
   // Set to true when this ImageData is a good candidate for reuse.
   bool is_candidate_for_reuse_;
-
-  DISALLOW_COPY_AND_ASSIGN(ImageData);
 };
 
 // PlatformImageData is a full featured image data resource which can access
@@ -89,6 +90,10 @@
   PlatformImageData(const ppapi::HostResource& resource,
                     const PP_ImageDataDesc& desc,
                     base::UnsafeSharedMemoryRegion image_region);
+
+  PlatformImageData(const PlatformImageData&) = delete;
+  PlatformImageData& operator=(const PlatformImageData&) = delete;
+
   ~PlatformImageData() override;
 
   // PPB_ImageData API.
@@ -101,8 +106,6 @@
 
   // Null when the image isn't mapped.
   std::unique_ptr<SkCanvas> mapped_canvas_;
-
-  DISALLOW_COPY_AND_ASSIGN(PlatformImageData);
 };
 #endif  // !defined(OS_NACL)
 
@@ -114,6 +117,10 @@
   SimpleImageData(const ppapi::HostResource& resource,
                   const PP_ImageDataDesc& desc,
                   base::UnsafeSharedMemoryRegion region);
+
+  SimpleImageData(const SimpleImageData&) = delete;
+  SimpleImageData& operator=(const SimpleImageData&) = delete;
+
   ~SimpleImageData() override;
 
   // PPB_ImageData API.
@@ -126,13 +133,15 @@
   base::WritableSharedMemoryMapping shm_mapping_;
   uint32_t size_;
   int map_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(SimpleImageData);
 };
 
 class PPB_ImageData_Proxy : public InterfaceProxy {
  public:
   PPB_ImageData_Proxy(Dispatcher* dispatcher);
+
+  PPB_ImageData_Proxy(const PPB_ImageData_Proxy&) = delete;
+  PPB_ImageData_Proxy& operator=(const PPB_ImageData_Proxy&) = delete;
+
   ~PPB_ImageData_Proxy() override;
 
   static PP_Resource CreateProxyResource(
@@ -186,8 +195,6 @@
 
   // Host->Plugin message handlers.
   void OnPluginMsgNotifyUnusedImageData(const HostResource& old_image_data);
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_ImageData_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppb_message_loop_proxy.h b/ppapi/proxy/ppb_message_loop_proxy.h
index 1956669..f74e07a 100644
--- a/ppapi/proxy/ppb_message_loop_proxy.h
+++ b/ppapi/proxy/ppb_message_loop_proxy.h
@@ -31,6 +31,10 @@
   // Construct the one MessageLoopResource for the main thread. This must be
   // invoked on the main thread.
   explicit MessageLoopResource(ForMainThread);
+
+  MessageLoopResource(const MessageLoopResource&) = delete;
+  MessageLoopResource& operator=(const MessageLoopResource&) = delete;
+
   ~MessageLoopResource() override;
 
   // Resource overrides.
@@ -113,19 +117,18 @@
   // created (when it's associated with a thread), we keep tasks posted here
   // until that happens. Once the loop_ is created, this is unused.
   std::vector<TaskInfo> pending_tasks_;
-
-  DISALLOW_COPY_AND_ASSIGN(MessageLoopResource);
 };
 
 class PPB_MessageLoop_Proxy : public InterfaceProxy {
  public:
   explicit PPB_MessageLoop_Proxy(Dispatcher* dispatcher);
+
+  PPB_MessageLoop_Proxy(const PPB_MessageLoop_Proxy&) = delete;
+  PPB_MessageLoop_Proxy& operator=(const PPB_MessageLoop_Proxy&) = delete;
+
   ~PPB_MessageLoop_Proxy() override;
 
   static const PPB_MessageLoop_1_0* GetInterface();
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PPB_MessageLoop_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppb_testing_proxy.h b/ppapi/proxy/ppb_testing_proxy.h
index 8340e79..21b7e89b 100644
--- a/ppapi/proxy/ppb_testing_proxy.h
+++ b/ppapi/proxy/ppb_testing_proxy.h
@@ -25,6 +25,10 @@
 class PPB_Testing_Proxy : public InterfaceProxy {
  public:
   explicit PPB_Testing_Proxy(Dispatcher* dispatcher);
+
+  PPB_Testing_Proxy(const PPB_Testing_Proxy&) = delete;
+  PPB_Testing_Proxy& operator=(const PPB_Testing_Proxy&) = delete;
+
   ~PPB_Testing_Proxy() override;
 
   static const PPB_Testing_Private* GetProxyInterface();
@@ -51,8 +55,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the plugin, this value is always NULL.
   const PPB_Testing_Private* ppb_testing_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_Testing_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppb_var_deprecated_proxy.h b/ppapi/proxy/ppb_var_deprecated_proxy.h
index c440381..bf8f314 100644
--- a/ppapi/proxy/ppb_var_deprecated_proxy.h
+++ b/ppapi/proxy/ppb_var_deprecated_proxy.h
@@ -26,6 +26,10 @@
 class PPB_Var_Deprecated_Proxy : public InterfaceProxy {
  public:
   explicit PPB_Var_Deprecated_Proxy(Dispatcher* dispatcher);
+
+  PPB_Var_Deprecated_Proxy(const PPB_Var_Deprecated_Proxy&) = delete;
+  PPB_Var_Deprecated_Proxy& operator=(const PPB_Var_Deprecated_Proxy&) = delete;
+
   ~PPB_Var_Deprecated_Proxy() override;
 
   static const PPB_Var_Deprecated* GetProxyInterface();
@@ -93,8 +97,6 @@
   const PPB_Var_Deprecated* ppb_var_impl_;
 
   base::WeakPtrFactory<PPB_Var_Deprecated_Proxy> task_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_Var_Deprecated_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppb_video_decoder_proxy.cc b/ppapi/proxy/ppb_video_decoder_proxy.cc
index 7d1d003..cff02dfd 100644
--- a/ppapi/proxy/ppb_video_decoder_proxy.cc
+++ b/ppapi/proxy/ppb_video_decoder_proxy.cc
@@ -29,6 +29,10 @@
  public:
   // You must call Init() before using this class.
   explicit VideoDecoder(const HostResource& resource);
+
+  VideoDecoder(const VideoDecoder&) = delete;
+  VideoDecoder& operator=(const VideoDecoder&) = delete;
+
   ~VideoDecoder() override;
 
   static VideoDecoder* Create(const HostResource& resource,
@@ -54,8 +58,6 @@
   void FlushACK(int32_t result);
   void ResetACK(int32_t result);
   void EndOfBitstreamACK(int32_t buffer_id, int32_t result);
-
-  DISALLOW_COPY_AND_ASSIGN(VideoDecoder);
 };
 
 VideoDecoder::VideoDecoder(const HostResource& decoder)
diff --git a/ppapi/proxy/ppb_video_decoder_proxy.h b/ppapi/proxy/ppb_video_decoder_proxy.h
index a74a874..aa7cddc 100644
--- a/ppapi/proxy/ppb_video_decoder_proxy.h
+++ b/ppapi/proxy/ppb_video_decoder_proxy.h
@@ -21,6 +21,10 @@
 class PPB_VideoDecoder_Proxy : public InterfaceProxy {
  public:
   explicit PPB_VideoDecoder_Proxy(Dispatcher* dispatcher);
+
+  PPB_VideoDecoder_Proxy(const PPB_VideoDecoder_Proxy&) = delete;
+  PPB_VideoDecoder_Proxy& operator=(const PPB_VideoDecoder_Proxy&) = delete;
+
   ~PPB_VideoDecoder_Proxy() override;
 
   // Creates a VideoDecoder object in the plugin process.
@@ -72,8 +76,6 @@
   void OnMsgResetACK(const ppapi::HostResource& decoder, int32_t result);
 
   ProxyCompletionCallbackFactory<PPB_VideoDecoder_Proxy> callback_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_VideoDecoder_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppb_x509_certificate_private_proxy.cc b/ppapi/proxy/ppb_x509_certificate_private_proxy.cc
index c742d89..bf1bd13 100644
--- a/ppapi/proxy/ppb_x509_certificate_private_proxy.cc
+++ b/ppapi/proxy/ppb_x509_certificate_private_proxy.cc
@@ -19,6 +19,10 @@
 class X509CertificatePrivate : public PPB_X509Certificate_Private_Shared {
  public:
   X509CertificatePrivate(PP_Instance instance);
+
+  X509CertificatePrivate(const X509CertificatePrivate&) = delete;
+  X509CertificatePrivate& operator=(const X509CertificatePrivate&) = delete;
+
   ~X509CertificatePrivate() override;
 
   bool ParseDER(const std::vector<char>& der,
@@ -26,8 +30,6 @@
 
  private:
   void SendToBrowser(IPC::Message* msg);
-
-  DISALLOW_COPY_AND_ASSIGN(X509CertificatePrivate);
 };
 
 X509CertificatePrivate::X509CertificatePrivate(PP_Instance instance)
diff --git a/ppapi/proxy/ppb_x509_certificate_private_proxy.h b/ppapi/proxy/ppb_x509_certificate_private_proxy.h
index 4a45117..5235bfb 100644
--- a/ppapi/proxy/ppb_x509_certificate_private_proxy.h
+++ b/ppapi/proxy/ppb_x509_certificate_private_proxy.h
@@ -18,6 +18,12 @@
     : public InterfaceProxy {
  public:
   explicit PPB_X509Certificate_Private_Proxy(Dispatcher* dispatcher);
+
+  PPB_X509Certificate_Private_Proxy(const PPB_X509Certificate_Private_Proxy&) =
+      delete;
+  PPB_X509Certificate_Private_Proxy& operator=(
+      const PPB_X509Certificate_Private_Proxy&) = delete;
+
   ~PPB_X509Certificate_Private_Proxy() override;
   static PP_Resource CreateProxyResource(PP_Instance instance);
 
@@ -25,9 +31,6 @@
   bool OnMessageReceived(const IPC::Message& msg) override;
 
   static const ApiID kApiID = API_ID_PPB_X509_CERTIFICATE_PRIVATE;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PPB_X509Certificate_Private_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_class_proxy.h b/ppapi/proxy/ppp_class_proxy.h
index 8ee1189a..0aa536c7 100644
--- a/ppapi/proxy/ppp_class_proxy.h
+++ b/ppapi/proxy/ppp_class_proxy.h
@@ -30,6 +30,10 @@
   // PPP_Class isn't a normal interface that you can query for, so this
   // constructor doesn't take an interface pointer.
   explicit PPP_Class_Proxy(Dispatcher* dispatcher);
+
+  PPP_Class_Proxy(const PPP_Class_Proxy&) = delete;
+  PPP_Class_Proxy& operator=(const PPP_Class_Proxy&) = delete;
+
   ~PPP_Class_Proxy() override;
 
   // Factory function used for registration (normal code can just use the
@@ -100,8 +104,6 @@
   bool ValidateUserData(int64_t ppp_class,
                         int64_t class_data,
                         SerializedVarOutParam* exception);
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_Class_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_find_proxy.h b/ppapi/proxy/ppp_find_proxy.h
index 4e0b783..26b9a8ac 100644
--- a/ppapi/proxy/ppp_find_proxy.h
+++ b/ppapi/proxy/ppp_find_proxy.h
@@ -18,6 +18,10 @@
 class PPP_Find_Proxy : public InterfaceProxy {
  public:
   explicit PPP_Find_Proxy(Dispatcher* dispatcher);
+
+  PPP_Find_Proxy(const PPP_Find_Proxy&) = delete;
+  PPP_Find_Proxy& operator=(const PPP_Find_Proxy&) = delete;
+
   ~PPP_Find_Proxy() override;
 
   static const PPP_Find_Private* GetProxyInterface();
@@ -37,8 +41,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_Find_Private* ppp_find_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_Find_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_graphics_3d_proxy.h b/ppapi/proxy/ppp_graphics_3d_proxy.h
index 1b6e91a..abed25f 100644
--- a/ppapi/proxy/ppp_graphics_3d_proxy.h
+++ b/ppapi/proxy/ppp_graphics_3d_proxy.h
@@ -17,6 +17,10 @@
 class PPP_Graphics3D_Proxy : public InterfaceProxy {
  public:
   explicit PPP_Graphics3D_Proxy(Dispatcher* dispatcher);
+
+  PPP_Graphics3D_Proxy(const PPP_Graphics3D_Proxy&) = delete;
+  PPP_Graphics3D_Proxy& operator=(const PPP_Graphics3D_Proxy&) = delete;
+
   ~PPP_Graphics3D_Proxy() override;
 
   static const PPP_Graphics3D* GetProxyInterface();
@@ -32,8 +36,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_Graphics3D* ppp_graphics_3d_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_Graphics3D_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_input_event_proxy.h b/ppapi/proxy/ppp_input_event_proxy.h
index 753714e..002f5f1 100644
--- a/ppapi/proxy/ppp_input_event_proxy.h
+++ b/ppapi/proxy/ppp_input_event_proxy.h
@@ -19,6 +19,10 @@
 class PPP_InputEvent_Proxy : public InterfaceProxy {
  public:
   explicit PPP_InputEvent_Proxy(Dispatcher* dispatcher);
+
+  PPP_InputEvent_Proxy(const PPP_InputEvent_Proxy&) = delete;
+  PPP_InputEvent_Proxy& operator=(const PPP_InputEvent_Proxy&) = delete;
+
   ~PPP_InputEvent_Proxy() override;
 
   static const PPP_InputEvent* GetProxyInterface();
@@ -38,8 +42,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_InputEvent* ppp_input_event_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_InputEvent_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_instance_private_proxy.h b/ppapi/proxy/ppp_instance_private_proxy.h
index f4ed0b8..3e6e176 100644
--- a/ppapi/proxy/ppp_instance_private_proxy.h
+++ b/ppapi/proxy/ppp_instance_private_proxy.h
@@ -21,6 +21,11 @@
 class PPP_Instance_Private_Proxy : public InterfaceProxy {
  public:
   explicit PPP_Instance_Private_Proxy(Dispatcher* dispatcher);
+
+  PPP_Instance_Private_Proxy(const PPP_Instance_Private_Proxy&) = delete;
+  PPP_Instance_Private_Proxy& operator=(const PPP_Instance_Private_Proxy&) =
+      delete;
+
   ~PPP_Instance_Private_Proxy() override;
 
   static const PPP_Instance_Private* GetProxyInterface();
@@ -37,8 +42,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_Instance_Private* ppp_instance_private_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_Instance_Private_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_messaging_proxy.h b/ppapi/proxy/ppp_messaging_proxy.h
index 753c771c..4decf1d 100644
--- a/ppapi/proxy/ppp_messaging_proxy.h
+++ b/ppapi/proxy/ppp_messaging_proxy.h
@@ -19,6 +19,10 @@
 class PPP_Messaging_Proxy : public InterfaceProxy {
  public:
   PPP_Messaging_Proxy(Dispatcher* dispatcher);
+
+  PPP_Messaging_Proxy(const PPP_Messaging_Proxy&) = delete;
+  PPP_Messaging_Proxy& operator=(const PPP_Messaging_Proxy&) = delete;
+
   ~PPP_Messaging_Proxy() override;
 
   // InterfaceProxy implementation.
@@ -36,8 +40,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_Messaging* ppp_messaging_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_Messaging_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_mouse_lock_proxy.h b/ppapi/proxy/ppp_mouse_lock_proxy.h
index dfb4513..26b16f5 100644
--- a/ppapi/proxy/ppp_mouse_lock_proxy.h
+++ b/ppapi/proxy/ppp_mouse_lock_proxy.h
@@ -17,6 +17,10 @@
 class PPP_MouseLock_Proxy : public InterfaceProxy {
  public:
   PPP_MouseLock_Proxy(Dispatcher* dispatcher);
+
+  PPP_MouseLock_Proxy(const PPP_MouseLock_Proxy&) = delete;
+  PPP_MouseLock_Proxy& operator=(const PPP_MouseLock_Proxy&) = delete;
+
   ~PPP_MouseLock_Proxy() override;
 
   static const PPP_MouseLock* GetProxyInterface();
@@ -32,8 +36,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_MouseLock* ppp_mouse_lock_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_MouseLock_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_pdf_proxy.h b/ppapi/proxy/ppp_pdf_proxy.h
index 6b7519c..ebb47ce1 100644
--- a/ppapi/proxy/ppp_pdf_proxy.h
+++ b/ppapi/proxy/ppp_pdf_proxy.h
@@ -18,6 +18,10 @@
 class PPP_Pdf_Proxy : public InterfaceProxy {
  public:
   explicit PPP_Pdf_Proxy(Dispatcher* dispatcher);
+
+  PPP_Pdf_Proxy(const PPP_Pdf_Proxy&) = delete;
+  PPP_Pdf_Proxy& operator=(const PPP_Pdf_Proxy&) = delete;
+
   ~PPP_Pdf_Proxy() override;
 
   static const PPP_Pdf* GetProxyInterface();
@@ -60,8 +64,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_Pdf* ppp_pdf_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_Pdf_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_printing_proxy.h b/ppapi/proxy/ppp_printing_proxy.h
index bf7c15a..25b66e85 100644
--- a/ppapi/proxy/ppp_printing_proxy.h
+++ b/ppapi/proxy/ppp_printing_proxy.h
@@ -25,6 +25,10 @@
 class PPP_Printing_Proxy : public InterfaceProxy {
  public:
   explicit PPP_Printing_Proxy(Dispatcher* dispatcher);
+
+  PPP_Printing_Proxy(const PPP_Printing_Proxy&) = delete;
+  PPP_Printing_Proxy& operator=(const PPP_Printing_Proxy&) = delete;
+
   ~PPP_Printing_Proxy() override;
 
   static const PPP_Printing_Dev* GetProxyInterface();
@@ -49,12 +53,9 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_Printing_Dev* ppp_printing_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_Printing_Proxy);
 };
 
 }  // namespace proxy
 }  // namespace ppapi
 
 #endif  // PPAPI_PROXY_PPP_PRINTING_PROXY_H_
-
diff --git a/ppapi/proxy/ppp_text_input_proxy.h b/ppapi/proxy/ppp_text_input_proxy.h
index 5771256..9d37eb7 100644
--- a/ppapi/proxy/ppp_text_input_proxy.h
+++ b/ppapi/proxy/ppp_text_input_proxy.h
@@ -19,6 +19,10 @@
 class PPP_TextInput_Proxy : public InterfaceProxy {
  public:
   PPP_TextInput_Proxy(Dispatcher* dispatcher);
+
+  PPP_TextInput_Proxy(const PPP_TextInput_Proxy&) = delete;
+  PPP_TextInput_Proxy& operator=(const PPP_TextInput_Proxy&) = delete;
+
   ~PPP_TextInput_Proxy() override;
 
   static const PPP_TextInput_Dev* GetProxyInterface();
@@ -35,8 +39,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_TextInput_Dev* ppp_text_input_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_TextInput_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/ppp_video_decoder_proxy.h b/ppapi/proxy/ppp_video_decoder_proxy.h
index 2429ce6..b1b570a 100644
--- a/ppapi/proxy/ppp_video_decoder_proxy.h
+++ b/ppapi/proxy/ppp_video_decoder_proxy.h
@@ -22,6 +22,10 @@
 class PPP_VideoDecoder_Proxy : public InterfaceProxy {
  public:
   explicit PPP_VideoDecoder_Proxy(Dispatcher* dispatcher);
+
+  PPP_VideoDecoder_Proxy(const PPP_VideoDecoder_Proxy&) = delete;
+  PPP_VideoDecoder_Proxy& operator=(const PPP_VideoDecoder_Proxy&) = delete;
+
   ~PPP_VideoDecoder_Proxy() override;
 
   static const PPP_VideoDecoder_Dev* GetProxyInterface();
@@ -46,8 +50,6 @@
   // pointer so we don't have to retrieve it from the dispatcher each time.
   // In the host, this value is always NULL.
   const PPP_VideoDecoder_Dev* ppp_video_decoder_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPP_VideoDecoder_Proxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/printing_resource.h b/ppapi/proxy/printing_resource.h
index a6598dab..f16cd78 100644
--- a/ppapi/proxy/printing_resource.h
+++ b/ppapi/proxy/printing_resource.h
@@ -22,6 +22,10 @@
  public:
   PrintingResource(Connection connection,
                    PP_Instance instance);
+
+  PrintingResource(const PrintingResource&) = delete;
+  PrintingResource& operator=(const PrintingResource&) = delete;
+
   ~PrintingResource() override;
 
   // Resource overrides.
@@ -38,8 +42,6 @@
       scoped_refptr<TrackedCallback> callback,
       const ResourceMessageReplyParams& params,
       const PP_PrintSettings_Dev& settings);
-
-  DISALLOW_COPY_AND_ASSIGN(PrintingResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/proxy_channel.h b/ppapi/proxy/proxy_channel.h
index dd4f7ac..a2a03b9 100644
--- a/ppapi/proxy/proxy_channel.h
+++ b/ppapi/proxy/proxy_channel.h
@@ -67,6 +67,9 @@
         base::ProcessId remote_pid) = 0;
   };
 
+  ProxyChannel(const ProxyChannel&) = delete;
+  ProxyChannel& operator=(const ProxyChannel&) = delete;
+
   ~ProxyChannel() override;
 
   // Alternative to InitWithChannel() for unit tests that want to send all
@@ -142,8 +145,6 @@
   // Will be null for some tests when there is a test_sink_, and if the
   // remote side has crashed.
   std::unique_ptr<IPC::SyncChannel> channel_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProxyChannel);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/proxy_object_var.h b/ppapi/proxy/proxy_object_var.h
index 0690129..43dde27a 100644
--- a/ppapi/proxy/proxy_object_var.h
+++ b/ppapi/proxy/proxy_object_var.h
@@ -25,6 +25,9 @@
  public:
   ProxyObjectVar(proxy::PluginDispatcher* dispatcher, int32_t host_var_id);
 
+  ProxyObjectVar(const ProxyObjectVar&) = delete;
+  ProxyObjectVar& operator=(const ProxyObjectVar&) = delete;
+
   ~ProxyObjectVar() override;
 
   // Var overrides.
@@ -51,8 +54,6 @@
   // plugin, this stores the user data so that we can look it up later. See
   // PluginVarTracker.
   void* user_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(ProxyObjectVar);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/proxy/raw_var_data.h b/ppapi/proxy/raw_var_data.h
index 4309ac6..6d6f5648 100644
--- a/ppapi/proxy/raw_var_data.h
+++ b/ppapi/proxy/raw_var_data.h
@@ -61,6 +61,10 @@
 
   // Constructs an empty RawVarDataGraph.
   RawVarDataGraph();
+
+  RawVarDataGraph(const RawVarDataGraph&) = delete;
+  RawVarDataGraph& operator=(const RawVarDataGraph&) = delete;
+
   ~RawVarDataGraph();
 
   // Construct a new PP_Var from the graph. All of the PP_Vars referenced by
@@ -89,8 +93,6 @@
  private:
   // A list of the nodes in the graph.
   std::vector<std::unique_ptr<RawVarData>> data_;
-
-  DISALLOW_COPY_AND_ASSIGN(RawVarDataGraph);
 };
 
 // Abstract base class for the data contained in a PP_Var.
diff --git a/ppapi/proxy/resource_creation_proxy.h b/ppapi/proxy/resource_creation_proxy.h
index 4058bcd17..f0637ba 100644
--- a/ppapi/proxy/resource_creation_proxy.h
+++ b/ppapi/proxy/resource_creation_proxy.h
@@ -29,6 +29,10 @@
                               public thunk::ResourceCreationAPI {
  public:
   explicit ResourceCreationProxy(Dispatcher* dispatcher);
+
+  ResourceCreationProxy(const ResourceCreationProxy&) = delete;
+  ResourceCreationProxy& operator=(const ResourceCreationProxy&) = delete;
+
   ~ResourceCreationProxy() override;
 
   // Factory function used for registration (normal code can just use the
@@ -174,7 +178,6 @@
 
  private:
   Connection GetConnection();
-  DISALLOW_COPY_AND_ASSIGN(ResourceCreationProxy);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/serialized_var.h b/ppapi/proxy/serialized_var.h
index ebdce45..cf51284 100644
--- a/ppapi/proxy/serialized_var.h
+++ b/ppapi/proxy/serialized_var.h
@@ -115,6 +115,10 @@
    public:
     Inner();
     Inner(VarSerializationRules* serialization_rules);
+
+    Inner(const Inner&) = delete;
+    Inner& operator=(const Inner&) = delete;
+
     ~Inner();
 
     VarSerializationRules* serialization_rules() {
@@ -199,8 +203,6 @@
     // (e.g. PP_VARTYPE_STRING). The data is stored in |raw_var_data_| and the
     // PP_Var is constructed when |GetVar()| is called.
     std::unique_ptr<RawVarDataGraph> raw_var_data_;
-
-    DISALLOW_COPY_AND_ASSIGN(Inner);
   };
 
   SerializedVar(VarSerializationRules* serialization_rules);
diff --git a/ppapi/proxy/tcp_server_socket_private_resource.h b/ppapi/proxy/tcp_server_socket_private_resource.h
index ea131e3..b92e177 100644
--- a/ppapi/proxy/tcp_server_socket_private_resource.h
+++ b/ppapi/proxy/tcp_server_socket_private_resource.h
@@ -23,6 +23,12 @@
       public thunk::PPB_TCPServerSocket_Private_API {
  public:
   TCPServerSocketPrivateResource(Connection connection, PP_Instance instance);
+
+  TCPServerSocketPrivateResource(const TCPServerSocketPrivateResource&) =
+      delete;
+  TCPServerSocketPrivateResource& operator=(
+      const TCPServerSocketPrivateResource&) = delete;
+
   ~TCPServerSocketPrivateResource() override;
 
   // PluginResource implementation.
@@ -59,8 +65,6 @@
 
   scoped_refptr<TrackedCallback> listen_callback_;
   scoped_refptr<TrackedCallback> accept_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(TCPServerSocketPrivateResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/tcp_socket_private_resource.h b/ppapi/proxy/tcp_socket_private_resource.h
index 0a36d1b7..90cb4c3 100644
--- a/ppapi/proxy/tcp_socket_private_resource.h
+++ b/ppapi/proxy/tcp_socket_private_resource.h
@@ -29,6 +29,9 @@
                            const PP_NetAddress_Private& local_addr,
                            const PP_NetAddress_Private& remote_addr);
 
+  TCPSocketPrivateResource(const TCPSocketPrivateResource&) = delete;
+  TCPSocketPrivateResource& operator=(const TCPSocketPrivateResource&) = delete;
+
   ~TCPSocketPrivateResource() override;
 
   // PluginResource overrides.
@@ -66,9 +69,6 @@
       int pending_host_id,
       const PP_NetAddress_Private& local_addr,
       const PP_NetAddress_Private& remote_addr) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TCPSocketPrivateResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/tcp_socket_resource.h b/ppapi/proxy/tcp_socket_resource.h
index 3266805d..98d9547 100644
--- a/ppapi/proxy/tcp_socket_resource.h
+++ b/ppapi/proxy/tcp_socket_resource.h
@@ -24,6 +24,9 @@
                     PP_Instance instance,
                     TCPSocketVersion version);
 
+  TCPSocketResource(const TCPSocketResource&) = delete;
+  TCPSocketResource& operator=(const TCPSocketResource&) = delete;
+
   ~TCPSocketResource() override;
 
   // PluginResource overrides.
@@ -68,8 +71,6 @@
                     int pending_host_id,
                     const PP_NetAddress_Private& local_addr,
                     const PP_NetAddress_Private& remote_addr);
-
-  DISALLOW_COPY_AND_ASSIGN(TCPSocketResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/udp_socket_private_resource.h b/ppapi/proxy/udp_socket_private_resource.h
index d57ef04..aaaf54d 100644
--- a/ppapi/proxy/udp_socket_private_resource.h
+++ b/ppapi/proxy/udp_socket_private_resource.h
@@ -21,6 +21,10 @@
       public thunk::PPB_UDPSocket_Private_API {
  public:
   UDPSocketPrivateResource(Connection connection, PP_Instance instance);
+
+  UDPSocketPrivateResource(const UDPSocketPrivateResource&) = delete;
+  UDPSocketPrivateResource& operator=(const UDPSocketPrivateResource&) = delete;
+
   ~UDPSocketPrivateResource() override;
 
   // PluginResource implementation.
@@ -41,9 +45,6 @@
                  const PP_NetAddress_Private* addr,
                  scoped_refptr<TrackedCallback> callback) override;
   void Close() override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(UDPSocketPrivateResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/udp_socket_resource.h b/ppapi/proxy/udp_socket_resource.h
index e7ba86d..d0a751f 100644
--- a/ppapi/proxy/udp_socket_resource.h
+++ b/ppapi/proxy/udp_socket_resource.h
@@ -20,6 +20,10 @@
                                              public thunk::PPB_UDPSocket_API {
  public:
   UDPSocketResource(Connection connection, PP_Instance instance);
+
+  UDPSocketResource(const UDPSocketResource&) = delete;
+  UDPSocketResource& operator=(const UDPSocketResource&) = delete;
+
   ~UDPSocketResource() override;
 
   // PluginResource implementation.
@@ -53,9 +57,6 @@
                     scoped_refptr<TrackedCallback> callback) override;
   int32_t LeaveGroup(PP_Resource group,
                      scoped_refptr<TrackedCallback> callback) override;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(UDPSocketResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/uma_private_resource.h b/ppapi/proxy/uma_private_resource.h
index 67eb67b..2fb40c03 100644
--- a/ppapi/proxy/uma_private_resource.h
+++ b/ppapi/proxy/uma_private_resource.h
@@ -22,6 +22,10 @@
       public thunk::PPB_UMA_Singleton_API {
  public:
   UMAPrivateResource(Connection connection, PP_Instance instance);
+
+  UMAPrivateResource(const UMAPrivateResource&) = delete;
+  UMAPrivateResource& operator=(const UMAPrivateResource&) = delete;
+
   ~UMAPrivateResource() override;
 
   // Resource overrides.
@@ -55,8 +59,6 @@
   void OnPluginMsgIsCrashReportingEnabled(
       const ResourceMessageReplyParams& params);
   scoped_refptr<TrackedCallback> pending_callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(UMAPrivateResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/url_loader_resource.h b/ppapi/proxy/url_loader_resource.h
index 9a38fd9..fb3ec5ce 100644
--- a/ppapi/proxy/url_loader_resource.h
+++ b/ppapi/proxy/url_loader_resource.h
@@ -40,6 +40,9 @@
                     int pending_main_document_loader_id,
                     const URLResponseInfoData& data);
 
+  URLLoaderResource(const URLLoaderResource&) = delete;
+  URLLoaderResource& operator=(const URLLoaderResource&) = delete;
+
   ~URLLoaderResource() override;
 
   // Resource override.
@@ -139,8 +142,6 @@
 
   // The response info if we've received it.
   scoped_refptr<URLResponseInfoResource> response_info_;
-
-  DISALLOW_COPY_AND_ASSIGN(URLLoaderResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/url_request_info_resource.h b/ppapi/proxy/url_request_info_resource.h
index 1ec7d13b..f04c968 100644
--- a/ppapi/proxy/url_request_info_resource.h
+++ b/ppapi/proxy/url_request_info_resource.h
@@ -23,6 +23,10 @@
  public:
   URLRequestInfoResource(Connection connection, PP_Instance instance,
                          const URLRequestInfoData& data);
+
+  URLRequestInfoResource(const URLRequestInfoResource&) = delete;
+  URLRequestInfoResource& operator=(const URLRequestInfoResource&) = delete;
+
   ~URLRequestInfoResource() override;
 
   // Resource overrides.
@@ -46,8 +50,6 @@
 
  private:
   URLRequestInfoData data_;
-
-  DISALLOW_COPY_AND_ASSIGN(URLRequestInfoResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/url_response_info_resource.h b/ppapi/proxy/url_response_info_resource.h
index 66f4949..81aa651 100644
--- a/ppapi/proxy/url_response_info_resource.h
+++ b/ppapi/proxy/url_response_info_resource.h
@@ -23,6 +23,10 @@
   URLResponseInfoResource(Connection connection,
                           PP_Instance instance,
                           const URLResponseInfoData& data);
+
+  URLResponseInfoResource(const URLResponseInfoResource&) = delete;
+  URLResponseInfoResource& operator=(const URLResponseInfoResource&) = delete;
+
   ~URLResponseInfoResource() override;
 
   // Resource override.
@@ -36,8 +40,6 @@
 
  private:
   URLResponseInfoData data_;
-
-  DISALLOW_COPY_AND_ASSIGN(URLResponseInfoResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/video_capture_resource.h b/ppapi/proxy/video_capture_resource.h
index 5a0e7f8..c64c24e 100644
--- a/ppapi/proxy/video_capture_resource.h
+++ b/ppapi/proxy/video_capture_resource.h
@@ -26,6 +26,10 @@
   VideoCaptureResource(Connection connection,
                        PP_Instance instance,
                        PluginDispatcher* dispatcher);
+
+  VideoCaptureResource(const VideoCaptureResource&) = delete;
+  VideoCaptureResource& operator=(const VideoCaptureResource&) = delete;
+
   ~VideoCaptureResource() override;
 
   // PluginResource override.
@@ -91,8 +95,6 @@
   OpenState open_state_;
 
   DeviceEnumerationResourceHelper enumeration_helper_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoCaptureResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/video_decoder_resource.h b/ppapi/proxy/video_decoder_resource.h
index 29e6b307..e399011 100644
--- a/ppapi/proxy/video_decoder_resource.h
+++ b/ppapi/proxy/video_decoder_resource.h
@@ -38,6 +38,10 @@
       public thunk::PPB_VideoDecoder_API {
  public:
   VideoDecoderResource(Connection connection, PP_Instance instance);
+
+  VideoDecoderResource(const VideoDecoderResource&) = delete;
+  VideoDecoderResource& operator=(const VideoDecoderResource&) = delete;
+
   ~VideoDecoderResource() override;
 
   // Resource overrides.
@@ -185,8 +189,6 @@
   bool initialized_;
   bool testing_;
   int32_t decoder_last_error_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoDecoderResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/video_encoder_resource.h b/ppapi/proxy/video_encoder_resource.h
index 266db95..0ba2373 100644
--- a/ppapi/proxy/video_encoder_resource.h
+++ b/ppapi/proxy/video_encoder_resource.h
@@ -34,6 +34,10 @@
       public ppapi::MediaStreamBufferManager::Delegate {
  public:
   VideoEncoderResource(Connection connection, PP_Instance instance);
+
+  VideoEncoderResource(const VideoEncoderResource&) = delete;
+  VideoEncoderResource& operator=(const VideoEncoderResource&) = delete;
+
   ~VideoEncoderResource() override;
 
   thunk::PPB_VideoEncoder_API* AsPPB_VideoEncoder_API() override;
@@ -154,8 +158,6 @@
 
   scoped_refptr<TrackedCallback> get_bitstream_buffer_callback_;
   PP_BitstreamBuffer* get_bitstream_buffer_data_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoEncoderResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/video_frame_resource.h b/ppapi/proxy/video_frame_resource.h
index d82518bd..7d0a882 100644
--- a/ppapi/proxy/video_frame_resource.h
+++ b/ppapi/proxy/video_frame_resource.h
@@ -24,6 +24,9 @@
                      int32_t index,
                      MediaStreamBuffer* buffer);
 
+  VideoFrameResource(const VideoFrameResource&) = delete;
+  VideoFrameResource& operator=(const VideoFrameResource&) = delete;
+
   ~VideoFrameResource() override;
 
   // PluginResource overrides:
@@ -44,8 +47,6 @@
   int32_t index_;
 
   MediaStreamBuffer* buffer_;
-
-  DISALLOW_COPY_AND_ASSIGN(VideoFrameResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/vpn_provider_resource.h b/ppapi/proxy/vpn_provider_resource.h
index 1915ed87..377bf6d 100644
--- a/ppapi/proxy/vpn_provider_resource.h
+++ b/ppapi/proxy/vpn_provider_resource.h
@@ -22,6 +22,10 @@
       public thunk::PPB_VpnProvider_API {
  public:
   VpnProviderResource(Connection connection, PP_Instance instance);
+
+  VpnProviderResource(const VpnProviderResource&) = delete;
+  VpnProviderResource& operator=(const VpnProviderResource&) = delete;
+
   virtual ~VpnProviderResource();
 
   // PluginResource implementation.
@@ -83,8 +87,6 @@
 
   // Connection bound state
   bool bound_;
-
-  DISALLOW_COPY_AND_ASSIGN(VpnProviderResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/proxy/websocket_resource.h b/ppapi/proxy/websocket_resource.h
index b50b385..a8cf9bf3 100644
--- a/ppapi/proxy/websocket_resource.h
+++ b/ppapi/proxy/websocket_resource.h
@@ -27,6 +27,10 @@
                                              public thunk::PPB_WebSocket_API {
  public:
   WebSocketResource(Connection connection, PP_Instance instance);
+
+  WebSocketResource(const WebSocketResource&) = delete;
+  WebSocketResource& operator=(const WebSocketResource&) = delete;
+
   ~WebSocketResource() override;
 
   // PluginResource implementation.
@@ -148,8 +152,6 @@
   // This value is used to calculate bufferedAmount in the WebSocket API
   // specification. The calculated value can be read via GetBufferedAmount().
   uint64_t buffered_amount_after_close_;
-
-  DISALLOW_COPY_AND_ASSIGN(WebSocketResource);
 };
 
 }  // namespace proxy
diff --git a/ppapi/shared_impl/array_writer.h b/ppapi/shared_impl/array_writer.h
index a301dcc..e97ed52 100644
--- a/ppapi/shared_impl/array_writer.h
+++ b/ppapi/shared_impl/array_writer.h
@@ -29,6 +29,10 @@
  public:
   ArrayWriter();  // Creates an is_null() object
   ArrayWriter(const PP_ArrayOutput& output);
+
+  ArrayWriter(const ArrayWriter&) = delete;
+  ArrayWriter& operator=(const ArrayWriter&) = delete;
+
   ~ArrayWriter();
 
   bool is_valid() const { return !!pp_array_output_.GetDataBuffer; }
@@ -112,8 +116,6 @@
 
  private:
   PP_ArrayOutput pp_array_output_;
-
-  DISALLOW_COPY_AND_ASSIGN(ArrayWriter);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/file_io_state_manager.h b/ppapi/shared_impl/file_io_state_manager.h
index 8e1e978..beb27af6 100644
--- a/ppapi/shared_impl/file_io_state_manager.h
+++ b/ppapi/shared_impl/file_io_state_manager.h
@@ -19,6 +19,10 @@
 class PPAPI_SHARED_EXPORT FileIOStateManager {
  public:
   FileIOStateManager();
+
+  FileIOStateManager(const FileIOStateManager&) = delete;
+  FileIOStateManager& operator=(const FileIOStateManager&) = delete;
+
   ~FileIOStateManager();
 
   enum OperationType {
@@ -59,8 +63,6 @@
 
   // Set to true when the file has been successfully opened.
   bool file_open_;
-
-  DISALLOW_COPY_AND_ASSIGN(FileIOStateManager);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/media_stream_buffer_manager.h b/ppapi/shared_impl/media_stream_buffer_manager.h
index 8d6cae7..259effc 100644
--- a/ppapi/shared_impl/media_stream_buffer_manager.h
+++ b/ppapi/shared_impl/media_stream_buffer_manager.h
@@ -51,6 +51,9 @@
   // it alive during the MediaStreamBufferManager's lifecycle.
   explicit MediaStreamBufferManager(Delegate* delegate);
 
+  MediaStreamBufferManager(const MediaStreamBufferManager&) = delete;
+  MediaStreamBufferManager& operator=(const MediaStreamBufferManager&) = delete;
+
   ~MediaStreamBufferManager();
 
   int32_t number_of_buffers() const { return number_of_buffers_; }
@@ -100,8 +103,6 @@
   // mapping.
   base::UnsafeSharedMemoryRegion region_;
   base::WritableSharedMemoryMapping mapping_;
-
-  DISALLOW_COPY_AND_ASSIGN(MediaStreamBufferManager);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h
index 90686e9..0dbeddd 100644
--- a/ppapi/shared_impl/ppapi_globals.h
+++ b/ppapi/shared_impl/ppapi_globals.h
@@ -46,6 +46,9 @@
   struct PerThreadForTest {};
   explicit PpapiGlobals(PerThreadForTest);
 
+  PpapiGlobals(const PpapiGlobals&) = delete;
+  PpapiGlobals& operator=(const PpapiGlobals&) = delete;
+
   virtual ~PpapiGlobals();
 
   // Getter for the global singleton.
@@ -127,8 +130,6 @@
   static PpapiGlobals* GetThreadLocalPointer();
 
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
-
-  DISALLOW_COPY_AND_ASSIGN(PpapiGlobals);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_audio_config_shared.h b/ppapi/shared_impl/ppb_audio_config_shared.h
index 643d1e19..3149dd3 100644
--- a/ppapi/shared_impl/ppb_audio_config_shared.h
+++ b/ppapi/shared_impl/ppb_audio_config_shared.h
@@ -26,6 +26,9 @@
     : public Resource,
       public thunk::PPB_AudioConfig_API {
  public:
+  PPB_AudioConfig_Shared(const PPB_AudioConfig_Shared&) = delete;
+  PPB_AudioConfig_Shared& operator=(const PPB_AudioConfig_Shared&) = delete;
+
   ~PPB_AudioConfig_Shared() override;
 
   static PP_Resource Create(ResourceObjectType type,
@@ -58,8 +61,6 @@
 
   PP_AudioSampleRate sample_rate_;
   uint32_t sample_frame_count_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_AudioConfig_Shared);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_audio_shared.h b/ppapi/shared_impl/ppb_audio_shared.h
index 1cac09e1c..cd21d1d4 100644
--- a/ppapi/shared_impl/ppb_audio_shared.h
+++ b/ppapi/shared_impl/ppb_audio_shared.h
@@ -52,6 +52,10 @@
       public base::DelegateSimpleThread::Delegate {
  public:
   PPB_Audio_Shared();
+
+  PPB_Audio_Shared(const PPB_Audio_Shared&) = delete;
+  PPB_Audio_Shared& operator=(const PPB_Audio_Shared&) = delete;
+
   virtual ~PPB_Audio_Shared();
 
   bool playing() const { return playing_; }
@@ -146,8 +150,6 @@
 
   // Buffer index used to coordinate with the browser side audio receiver.
   uint32_t buffer_index_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_Audio_Shared);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_message_loop_shared.h b/ppapi/shared_impl/ppb_message_loop_shared.h
index 925806d..a2086c5 100644
--- a/ppapi/shared_impl/ppb_message_loop_shared.h
+++ b/ppapi/shared_impl/ppb_message_loop_shared.h
@@ -36,6 +36,10 @@
   // invoked on the main thread.
   struct ForMainThread {};
   explicit MessageLoopShared(ForMainThread);
+
+  MessageLoopShared(const MessageLoopShared&) = delete;
+  MessageLoopShared& operator=(const MessageLoopShared&) = delete;
+
   virtual ~MessageLoopShared();
 
   // Handles posting to the message loop if there is one, or the pending queue
@@ -53,8 +57,6 @@
   // from JavaScript. This is used to make it illegal to use blocking callbacks
   // while the thread is handling a blocking message.
   virtual bool CurrentlyHandlingBlockingMessage() = 0;
-
-  DISALLOW_COPY_AND_ASSIGN(MessageLoopShared);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_video_decoder_shared.h b/ppapi/shared_impl/ppb_video_decoder_shared.h
index 2726dbad..d6bd67e 100644
--- a/ppapi/shared_impl/ppb_video_decoder_shared.h
+++ b/ppapi/shared_impl/ppb_video_decoder_shared.h
@@ -33,6 +33,10 @@
  public:
   explicit PPB_VideoDecoder_Shared(PP_Instance instance);
   explicit PPB_VideoDecoder_Shared(const HostResource& host_resource);
+
+  PPB_VideoDecoder_Shared(const PPB_VideoDecoder_Shared&) = delete;
+  PPB_VideoDecoder_Shared& operator=(const PPB_VideoDecoder_Shared&) = delete;
+
   ~PPB_VideoDecoder_Shared() override;
 
   // Resource overrides.
@@ -76,8 +80,6 @@
   // In the out-of-process case, Graphics3D's gles2_impl() exists in the plugin
   // process only, so gles2_impl_ is NULL in that case.
   gpu::gles2::GLES2Implementation* gles2_impl_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_VideoDecoder_Shared);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/ppb_view_shared.h b/ppapi/shared_impl/ppb_view_shared.h
index 0693451..fb87e69 100644
--- a/ppapi/shared_impl/ppb_view_shared.h
+++ b/ppapi/shared_impl/ppb_view_shared.h
@@ -37,6 +37,10 @@
   PPB_View_Shared(ResourceObjectType type,
                   PP_Instance instance,
                   const ViewData& data);
+
+  PPB_View_Shared(const PPB_View_Shared&) = delete;
+  PPB_View_Shared& operator=(const PPB_View_Shared&) = delete;
+
   ~PPB_View_Shared() override;
 
   // Resource overrides.
@@ -55,8 +59,6 @@
 
  private:
   ViewData data_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_View_Shared);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h
index 3878c41c..2f852e5a 100644
--- a/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h
+++ b/ppapi/shared_impl/private/ppb_x509_certificate_private_shared.h
@@ -53,6 +53,12 @@
   PPB_X509Certificate_Private_Shared(ResourceObjectType type,
                                      PP_Instance instance,
                                      const PPB_X509Certificate_Fields& fields);
+
+  PPB_X509Certificate_Private_Shared(
+      const PPB_X509Certificate_Private_Shared&) = delete;
+  PPB_X509Certificate_Private_Shared& operator=(
+      const PPB_X509Certificate_Private_Shared&) = delete;
+
   ~PPB_X509Certificate_Private_Shared() override;
 
   // Resource overrides.
@@ -68,8 +74,6 @@
 
  private:
   std::unique_ptr<PPB_X509Certificate_Fields> fields_;
-
-  DISALLOW_COPY_AND_ASSIGN(PPB_X509Certificate_Private_Shared);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/proxy_lock.h b/ppapi/shared_impl/proxy_lock.h
index 04ae041..24d8cfb 100644
--- a/ppapi/shared_impl/proxy_lock.h
+++ b/ppapi/shared_impl/proxy_lock.h
@@ -83,10 +83,11 @@
 class ProxyAutoLock {
  public:
   ProxyAutoLock() { ProxyLock::Acquire(); }
-  ~ProxyAutoLock() { ProxyLock::Release(); }
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(ProxyAutoLock);
+  ProxyAutoLock(const ProxyAutoLock&) = delete;
+  ProxyAutoLock& operator=(const ProxyAutoLock&) = delete;
+
+  ~ProxyAutoLock() { ProxyLock::Release(); }
 };
 
 // The inverse of the above; unlock on construction, lock on destruction. This
@@ -96,10 +97,11 @@
 class ProxyAutoUnlock {
  public:
   ProxyAutoUnlock() { ProxyLock::Release(); }
-  ~ProxyAutoUnlock() { ProxyLock::Acquire(); }
 
- private:
-  DISALLOW_COPY_AND_ASSIGN(ProxyAutoUnlock);
+  ProxyAutoUnlock(const ProxyAutoUnlock&) = delete;
+  ProxyAutoUnlock& operator=(const ProxyAutoUnlock&) = delete;
+
+  ~ProxyAutoUnlock() { ProxyLock::Acquire(); }
 };
 
 // A set of function template overloads for invoking a function pointer while
@@ -206,6 +208,9 @@
     }
   }
 
+  RunWhileLockedHelper(const RunWhileLockedHelper&) = delete;
+  RunWhileLockedHelper& operator=(const RunWhileLockedHelper&) = delete;
+
   ~RunWhileLockedHelper() {
     // Check that the Callback is destroyed on the same thread as where
     // CallWhileLocked happened if CallWhileLocked happened. If we weren't
@@ -239,7 +244,6 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
   CallbackType callback_;
 
   // Used to ensure that the Callback is run and deleted on the same thread.
@@ -267,6 +271,10 @@
       std::move(temp_callback).Run(p1);
     }
   }
+
+  RunWhileLockedHelper(const RunWhileLockedHelper&) = delete;
+  RunWhileLockedHelper& operator=(const RunWhileLockedHelper&) = delete;
+
   ~RunWhileLockedHelper() {
     DCHECK(thread_checker_.CalledOnValidThread());
     if (callback_) {
@@ -280,7 +288,6 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
   CallbackType callback_;
   base::ThreadChecker thread_checker_;
 };
@@ -307,6 +314,10 @@
       std::move(temp_callback).Run(p1, p2);
     }
   }
+
+  RunWhileLockedHelper(const RunWhileLockedHelper&) = delete;
+  RunWhileLockedHelper& operator=(const RunWhileLockedHelper&) = delete;
+
   ~RunWhileLockedHelper() {
     DCHECK(thread_checker_.CalledOnValidThread());
     if (callback_) {
@@ -320,7 +331,6 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
   CallbackType callback_;
   base::ThreadChecker thread_checker_;
 };
@@ -348,6 +358,10 @@
       std::move(temp_callback).Run(p1, p2, p3);
     }
   }
+
+  RunWhileLockedHelper(const RunWhileLockedHelper&) = delete;
+  RunWhileLockedHelper& operator=(const RunWhileLockedHelper&) = delete;
+
   ~RunWhileLockedHelper() {
     DCHECK(thread_checker_.CalledOnValidThread());
     if (callback_) {
@@ -361,7 +375,6 @@
   }
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(RunWhileLockedHelper);
   CallbackType callback_;
   base::ThreadChecker thread_checker_;
 };
diff --git a/ppapi/shared_impl/resource_tracker.h b/ppapi/shared_impl/resource_tracker.h
index 04f26b86..373090f 100644
--- a/ppapi/shared_impl/resource_tracker.h
+++ b/ppapi/shared_impl/resource_tracker.h
@@ -31,6 +31,10 @@
   // CheckThreadingPreconditions() for more details.
   enum ThreadMode { SINGLE_THREADED, THREAD_SAFE };
   explicit ResourceTracker(ThreadMode thread_mode);
+
+  ResourceTracker(const ResourceTracker&) = delete;
+  ResourceTracker& operator=(const ResourceTracker&) = delete;
+
   virtual ~ResourceTracker();
 
   // The returned pointer will be NULL if there is no resource. The reference
@@ -132,8 +136,6 @@
   std::unique_ptr<base::ThreadChecker> thread_checker_;
 
   base::WeakPtrFactory<ResourceTracker> weak_ptr_factory_{this};
-
-  DISALLOW_COPY_AND_ASSIGN(ResourceTracker);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/scoped_pp_var.h b/ppapi/shared_impl/scoped_pp_var.h
index a88e417e..6e8899c 100644
--- a/ppapi/shared_impl/scoped_pp_var.h
+++ b/ppapi/shared_impl/scoped_pp_var.h
@@ -60,6 +60,10 @@
                    size_t size);
 
   explicit ScopedPPVarArray(size_t size);
+
+  ScopedPPVarArray(const ScopedPPVarArray&) = delete;
+  ScopedPPVarArray& operator=(const ScopedPPVarArray&) = delete;
+
   ~ScopedPPVarArray();
 
   // Passes ownership of the vars and the underlying array memory to the caller.
@@ -74,9 +78,6 @@
   const PP_Var& operator[](size_t index) { return array_[index]; }
 
  private:
-  // TODO(raymes): Consider supporting copy/assign.
-  DISALLOW_COPY_AND_ASSIGN(ScopedPPVarArray);
-
   PP_Var* array_;
   size_t size_;
 };
diff --git a/ppapi/shared_impl/test_globals.h b/ppapi/shared_impl/test_globals.h
index 776c3a44..89a4d85 100644
--- a/ppapi/shared_impl/test_globals.h
+++ b/ppapi/shared_impl/test_globals.h
@@ -59,6 +59,10 @@
  public:
   TestGlobals();
   explicit TestGlobals(PpapiGlobals::PerThreadForTest);
+
+  TestGlobals(const TestGlobals&) = delete;
+  TestGlobals& operator=(const TestGlobals&) = delete;
+
   ~TestGlobals() override;
 
   // PpapiGlobals implementation.
@@ -87,8 +91,6 @@
   ResourceTracker resource_tracker_;
   TestVarTracker var_tracker_;
   scoped_refptr<CallbackTracker> callback_tracker_;
-
-  DISALLOW_COPY_AND_ASSIGN(TestGlobals);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/var.h b/ppapi/shared_impl/var.h
index af259a7f..2e726c82 100644
--- a/ppapi/shared_impl/var.h
+++ b/ppapi/shared_impl/var.h
@@ -104,6 +104,10 @@
  public:
   explicit StringVar(const std::string& str);
   StringVar(const char* str, uint32_t len);
+
+  StringVar(const StringVar&) = delete;
+  StringVar& operator=(const StringVar&) = delete;
+
   ~StringVar() override;
 
   const std::string& value() const { return value_; }
@@ -140,8 +144,6 @@
   StringVar();  // Makes an empty string.
 
   std::string value_;
-
-  DISALLOW_COPY_AND_ASSIGN(StringVar);
 };
 
 // ArrayBufferVar --------------------------------------------------------------
@@ -161,6 +163,10 @@
 class PPAPI_SHARED_EXPORT ArrayBufferVar : public Var {
  public:
   ArrayBufferVar();
+
+  ArrayBufferVar(const ArrayBufferVar&) = delete;
+  ArrayBufferVar& operator=(const ArrayBufferVar&) = delete;
+
   ~ArrayBufferVar() override;
 
   virtual void* Map() = 0;
@@ -186,9 +192,6 @@
   // Helper function that converts a PP_Var to an ArrayBufferVar. This will
   // return NULL if the PP_Var is not of ArrayBuffer type.
   static ArrayBufferVar* FromPPVar(PP_Var var);
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(ArrayBufferVar);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/var_tracker.h b/ppapi/shared_impl/var_tracker.h
index 7ad45dea9..54b3cb26 100644
--- a/ppapi/shared_impl/var_tracker.h
+++ b/ppapi/shared_impl/var_tracker.h
@@ -51,6 +51,10 @@
   // CheckThreadingPreconditions() for more details.
   enum ThreadMode { SINGLE_THREADED, THREAD_SAFE };
   explicit VarTracker(ThreadMode thread_mode);
+
+  VarTracker(const VarTracker&) = delete;
+  VarTracker& operator=(const VarTracker&) = delete;
+
   virtual ~VarTracker();
 
   // Called by the Var object to add a new var to the tracker.
@@ -237,8 +241,6 @@
   // other threads (especially the IO thread). On the plugin side, the tracker
   // is protected by the proxy lock and is thread-safe, so this will be NULL.
   std::unique_ptr<base::ThreadChecker> thread_checker_;
-
-  DISALLOW_COPY_AND_ASSIGN(VarTracker);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/shared_impl/vpn_provider_util.h b/ppapi/shared_impl/vpn_provider_util.h
index 6013c92..f982467c 100644
--- a/ppapi/shared_impl/vpn_provider_util.h
+++ b/ppapi/shared_impl/vpn_provider_util.h
@@ -19,6 +19,10 @@
                           uint32_t packet_size,
                           base::UnsafeSharedMemoryRegion shm,
                           base::WritableSharedMemoryMapping mapping);
+
+  VpnProviderSharedBuffer(const VpnProviderSharedBuffer&) = delete;
+  VpnProviderSharedBuffer& operator=(const VpnProviderSharedBuffer&) = delete;
+
   ~VpnProviderSharedBuffer();
 
   bool GetAvailable(uint32_t* id);
@@ -33,8 +37,6 @@
   base::UnsafeSharedMemoryRegion shm_;
   base::WritableSharedMemoryMapping shm_mapping_;
   std::vector<bool> available_;
-
-  DISALLOW_COPY_AND_ASSIGN(VpnProviderSharedBuffer);
 };
 
 }  // namespace ppapi
diff --git a/ppapi/thunk/enter.h b/ppapi/thunk/enter.h
index 470ecd2..43b0d86 100644
--- a/ppapi/thunk/enter.h
+++ b/ppapi/thunk/enter.h
@@ -184,6 +184,10 @@
       : EnterBase(resource, callback) {
     Init(resource, report_error);
   }
+
+  EnterResource(const EnterResource&) = delete;
+  EnterResource& operator=(const EnterResource&) = delete;
+
   ~EnterResource() {}
 
   ResourceT* object() { return object_; }
@@ -201,8 +205,6 @@
   }
 
   ResourceT* object_;
-
-  DISALLOW_COPY_AND_ASSIGN(EnterResource);
 };
 
 // ----------------------------------------------------------------------------
diff --git a/printing/backend/BUILD.gn b/printing/backend/BUILD.gn
index b755e2191..7ac51f8 100644
--- a/printing/backend/BUILD.gn
+++ b/printing/backend/BUILD.gn
@@ -35,7 +35,6 @@
   public_configs = []
   configs += [ "//build/config/compiler:noshadowing" ]
   cflags = []
-  libs = []
   defines = [ "IS_PRINT_BACKEND_IMPL" ]
 
   public_deps = [ "//printing/buildflags" ]
@@ -66,11 +65,7 @@
       "printing_info_win.h",
       "win_helper.cc",
       "win_helper.h",
-      "xps_module.cc",
-      "xps_module.h",
     ]
-
-    libs += [ "prntvpt.lib" ]
   }
 
   if (use_cups) {
diff --git a/printing/backend/print_backend.h b/printing/backend/print_backend.h
index 53864f5..1565c60b 100644
--- a/printing/backend/print_backend.h
+++ b/printing/backend/print_backend.h
@@ -198,6 +198,8 @@
   // This is usually a lighter implementation than GetPrinterCapsAndDefaults().
   // Implementations must check `printer_name` validity in the same way as
   // IsValidPrinter().
+  // NOTE: on some old platforms (WinXP without XPS pack)
+  // GetPrinterCapsAndDefaults() will fail, while this function will succeed.
   virtual mojom::ResultCode GetPrinterSemanticCapsAndDefaults(
       const std::string& printer_name,
       PrinterSemanticCapsAndDefaults* printer_info) = 0;
diff --git a/printing/backend/print_backend_win.cc b/printing/backend/print_backend_win.cc
index 951fc0b..92844c6 100644
--- a/printing/backend/print_backend_win.cc
+++ b/printing/backend/print_backend_win.cc
@@ -25,7 +25,6 @@
 #include "printing/backend/print_backend_consts.h"
 #include "printing/backend/printing_info_win.h"
 #include "printing/backend/win_helper.h"
-#include "printing/backend/xps_module.h"
 #include "printing/mojom/print.mojom.h"
 
 namespace printing {
@@ -380,7 +379,7 @@
 
   HPTPROVIDER provider = nullptr;
   std::wstring wide_printer_name = base::UTF8ToWide(printer_name);
-  HRESULT hr = xps_module::OpenProvider(wide_printer_name, 1, &provider);
+  HRESULT hr = XPSModule::OpenProvider(wide_printer_name, 1, &provider);
   if (!provider)
     return mojom::ResultCode::kSuccess;
 
@@ -390,7 +389,7 @@
     DCHECK(SUCCEEDED(hr));
     if (print_capabilities_stream.Get()) {
       base::win::ScopedBstr error;
-      hr = xps_module::GetPrintCapabilities(
+      hr = XPSModule::GetPrintCapabilities(
           provider, nullptr, print_capabilities_stream.Get(), error.Receive());
       DCHECK(SUCCEEDED(hr));
       if (FAILED(hr)) {
@@ -416,7 +415,7 @@
       DCHECK(SUCCEEDED(hr));
       if (printer_defaults_stream.Get()) {
         DWORD dm_size = devmode_out->dmSize + devmode_out->dmDriverExtra;
-        hr = xps_module::ConvertDevModeToPrintTicket(
+        hr = XPSModule::ConvertDevModeToPrintTicket(
             provider, dm_size, devmode_out.get(), kPTJobScope,
             printer_defaults_stream.Get());
         DCHECK(SUCCEEDED(hr));
@@ -428,7 +427,7 @@
         }
       }
     }
-    xps_module::CloseProvider(provider);
+    XPSModule::CloseProvider(provider);
   }
   return mojom::ResultCode::kSuccess;
 }
diff --git a/printing/backend/win_helper.cc b/printing/backend/win_helper.cc
index 10a3ed6..067e186c 100644
--- a/printing/backend/win_helper.cc
+++ b/printing/backend/win_helper.cc
@@ -26,10 +26,46 @@
 #include "printing/backend/print_backend.h"
 #include "printing/backend/print_backend_consts.h"
 #include "printing/backend/printing_info_win.h"
-#include "printing/backend/xps_module.h"
 
 namespace {
 
+typedef HRESULT(WINAPI* PTOpenProviderProc)(PCWSTR printer_name,
+                                            DWORD version,
+                                            HPTPROVIDER* provider);
+
+typedef HRESULT(WINAPI* PTGetPrintCapabilitiesProc)(HPTPROVIDER provider,
+                                                    IStream* print_ticket,
+                                                    IStream* capabilities,
+                                                    BSTR* error_message);
+
+typedef HRESULT(WINAPI* PTConvertDevModeToPrintTicketProc)(
+    HPTPROVIDER provider,
+    ULONG devmode_size_in_bytes,
+    PDEVMODE devmode,
+    EPrintTicketScope scope,
+    IStream* print_ticket);
+
+typedef HRESULT(WINAPI* PTConvertPrintTicketToDevModeProc)(
+    HPTPROVIDER provider,
+    IStream* print_ticket,
+    EDefaultDevmodeType base_devmode_type,
+    EPrintTicketScope scope,
+    ULONG* devmode_byte_count,
+    PDEVMODE* devmode,
+    BSTR* error_message);
+
+typedef HRESULT(WINAPI* PTMergeAndValidatePrintTicketProc)(
+    HPTPROVIDER provider,
+    IStream* base_ticket,
+    IStream* delta_ticket,
+    EPrintTicketScope scope,
+    IStream* result_ticket,
+    BSTR* error_message);
+
+typedef HRESULT(WINAPI* PTReleaseMemoryProc)(PVOID buffer);
+
+typedef HRESULT(WINAPI* PTCloseProviderProc)(HPTPROVIDER provider);
+
 typedef HRESULT(WINAPI* StartXpsPrintJobProc)(
     const LPCWSTR printer_name,
     const LPCWSTR job_name,
@@ -42,6 +78,16 @@
     IXpsPrintJobStream** document_stream,
     IXpsPrintJobStream** print_ticket_stream);
 
+PTOpenProviderProc g_open_provider_proc = nullptr;
+PTGetPrintCapabilitiesProc g_get_print_capabilities_proc = nullptr;
+PTConvertDevModeToPrintTicketProc g_convert_devmode_to_print_ticket_proc =
+    nullptr;
+PTConvertPrintTicketToDevModeProc g_convert_print_ticket_to_devmode_proc =
+    nullptr;
+PTMergeAndValidatePrintTicketProc g_merge_and_validate_print_ticket_proc =
+    nullptr;
+PTReleaseMemoryProc g_release_memory_proc = nullptr;
+PTCloseProviderProc g_close_provider_proc = nullptr;
 StartXpsPrintJobProc g_start_xps_print_job_proc = nullptr;
 
 typedef std::string (*GetDisplayNameFunc)(const std::string& printer_name);
@@ -108,7 +154,134 @@
   return IsValid();
 }
 
-ScopedXPSInitializer::ScopedXPSInitializer() {
+bool XPSModule::Init() {
+  static bool initialized = InitImpl();
+  return initialized;
+}
+
+bool XPSModule::InitImpl() {
+  HMODULE prntvpt_module = LoadLibrary(L"prntvpt.dll");
+  if (!prntvpt_module)
+    return false;
+  g_open_provider_proc = reinterpret_cast<PTOpenProviderProc>(
+      GetProcAddress(prntvpt_module, "PTOpenProvider"));
+  if (!g_open_provider_proc) {
+    NOTREACHED();
+    return false;
+  }
+  g_get_print_capabilities_proc = reinterpret_cast<PTGetPrintCapabilitiesProc>(
+      GetProcAddress(prntvpt_module, "PTGetPrintCapabilities"));
+  if (!g_get_print_capabilities_proc) {
+    NOTREACHED();
+    return false;
+  }
+  g_convert_devmode_to_print_ticket_proc =
+      reinterpret_cast<PTConvertDevModeToPrintTicketProc>(
+          GetProcAddress(prntvpt_module, "PTConvertDevModeToPrintTicket"));
+  if (!g_convert_devmode_to_print_ticket_proc) {
+    NOTREACHED();
+    return false;
+  }
+  g_convert_print_ticket_to_devmode_proc =
+      reinterpret_cast<PTConvertPrintTicketToDevModeProc>(
+          GetProcAddress(prntvpt_module, "PTConvertPrintTicketToDevMode"));
+  if (!g_convert_print_ticket_to_devmode_proc) {
+    NOTREACHED();
+    return false;
+  }
+  g_merge_and_validate_print_ticket_proc =
+      reinterpret_cast<PTMergeAndValidatePrintTicketProc>(
+          GetProcAddress(prntvpt_module, "PTMergeAndValidatePrintTicket"));
+  if (!g_merge_and_validate_print_ticket_proc) {
+    NOTREACHED();
+    return false;
+  }
+  g_release_memory_proc = reinterpret_cast<PTReleaseMemoryProc>(
+      GetProcAddress(prntvpt_module, "PTReleaseMemory"));
+  if (!g_release_memory_proc) {
+    NOTREACHED();
+    return false;
+  }
+  g_close_provider_proc = reinterpret_cast<PTCloseProviderProc>(
+      GetProcAddress(prntvpt_module, "PTCloseProvider"));
+  if (!g_close_provider_proc) {
+    NOTREACHED();
+    return false;
+  }
+  return true;
+}
+
+HRESULT XPSModule::OpenProvider(const std::wstring& printer_name,
+                                DWORD version,
+                                HPTPROVIDER* provider) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  return g_open_provider_proc(printer_name.c_str(), version, provider);
+}
+
+HRESULT XPSModule::GetPrintCapabilities(HPTPROVIDER provider,
+                                        IStream* print_ticket,
+                                        IStream* capabilities,
+                                        BSTR* error_message) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  return g_get_print_capabilities_proc(provider, print_ticket, capabilities,
+                                       error_message);
+}
+
+HRESULT XPSModule::ConvertDevModeToPrintTicket(HPTPROVIDER provider,
+                                               ULONG devmode_size_in_bytes,
+                                               PDEVMODE devmode,
+                                               EPrintTicketScope scope,
+                                               IStream* print_ticket) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  return g_convert_devmode_to_print_ticket_proc(provider, devmode_size_in_bytes,
+                                                devmode, scope, print_ticket);
+}
+
+HRESULT XPSModule::ConvertPrintTicketToDevMode(
+    HPTPROVIDER provider,
+    IStream* print_ticket,
+    EDefaultDevmodeType base_devmode_type,
+    EPrintTicketScope scope,
+    ULONG* devmode_byte_count,
+    PDEVMODE* devmode,
+    BSTR* error_message) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  return g_convert_print_ticket_to_devmode_proc(
+      provider, print_ticket, base_devmode_type, scope, devmode_byte_count,
+      devmode, error_message);
+}
+
+HRESULT XPSModule::MergeAndValidatePrintTicket(HPTPROVIDER provider,
+                                               IStream* base_ticket,
+                                               IStream* delta_ticket,
+                                               EPrintTicketScope scope,
+                                               IStream* result_ticket,
+                                               BSTR* error_message) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  return g_merge_and_validate_print_ticket_proc(
+      provider, base_ticket, delta_ticket, scope, result_ticket, error_message);
+}
+
+HRESULT XPSModule::ReleaseMemory(PVOID buffer) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  return g_release_memory_proc(buffer);
+}
+
+HRESULT XPSModule::CloseProvider(HPTPROVIDER provider) {
+  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
+                                                base::BlockingType::MAY_BLOCK);
+  return g_close_provider_proc(provider);
+}
+
+ScopedXPSInitializer::ScopedXPSInitializer() : initialized_(false) {
+  if (!XPSModule::Init())
+    return;
   // Calls to XPS APIs typically require the XPS provider to be opened with
   // PTOpenProvider. PTOpenProvider calls CoInitializeEx with
   // COINIT_MULTITHREADED. We have seen certain buggy HP printer driver DLLs
@@ -256,7 +429,10 @@
     const std::string& print_ticket) {
   std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode;
   ScopedXPSInitializer xps_initializer;
-  CHECK(xps_initializer.initialized());
+  if (!xps_initializer.initialized()) {
+    // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll)
+    return dev_mode;
+  }
 
   ScopedPrinterHandle printer;
   if (!printer.OpenPrinterWithName(printer_name.c_str()))
@@ -268,21 +444,21 @@
     return dev_mode;
 
   HPTPROVIDER provider = nullptr;
-  hr = xps_module::OpenProvider(printer_name, 1, &provider);
+  hr = XPSModule::OpenProvider(printer_name, 1, &provider);
   if (SUCCEEDED(hr)) {
     ULONG size = 0;
     DEVMODE* dm = nullptr;
-    // Use `kPTJobScope`, because `kPTDocumentScope` breaks duplex.
-    hr = xps_module::ConvertPrintTicketToDevMode(
+    // Use kPTJobScope, because kPTDocumentScope breaks duplex.
+    hr = XPSModule::ConvertPrintTicketToDevMode(
         provider, pt_stream.Get(), kUserDefaultDevmode, kPTJobScope, &size, &dm,
         nullptr);
     if (SUCCEEDED(hr)) {
       // Correct DEVMODE using DocumentProperties. See documentation for
-      // PTConvertPrintTicketToDevMode().
+      // PTConvertPrintTicketToDevMode.
       dev_mode = CreateDevMode(printer.Get(), dm);
-      xps_module::ReleaseMemory(dm);
+      XPSModule::ReleaseMemory(dm);
     }
-    xps_module::CloseProvider(provider);
+    XPSModule::CloseProvider(provider);
   }
   return dev_mode;
 }
diff --git a/printing/backend/win_helper.h b/printing/backend/win_helper.h
index a7ebd13a..09aff42 100644
--- a/printing/backend/win_helper.h
+++ b/printing/backend/win_helper.h
@@ -6,6 +6,7 @@
 #define PRINTING_BACKEND_WIN_HELPER_H_
 
 #include <objidl.h>
+#include <prntvpt.h>
 
 // Important to include wincrypt_shim.h before xpsprint.h since
 // xpsprint.h includes <wincrypt.h> (xpsprint.h -> msopc.h ->
@@ -69,6 +70,50 @@
     base::win::GenericScopedHandle<PrinterChangeHandleTraits,
                                    base::win::DummyVerifierTraits>;
 
+// Wrapper class to wrap the XPS APIs (PTxxx APIs). This is needed because these
+// APIs are not available by default on XP. We could delayload prntvpt.dll but
+// this would mean having to add that to every binary that links with
+// printing.lib (which is a LOT of binaries). So choosing the GetProcAddress
+// route instead).
+class COMPONENT_EXPORT(PRINT_BACKEND) XPSModule {
+ public:
+  // All the other methods can ONLY be called after a successful call to Init.
+  // Init can be called many times and by multiple threads.
+  static bool Init();
+  static HRESULT OpenProvider(const std::wstring& printer_name,
+                              DWORD version,
+                              HPTPROVIDER* provider);
+  static HRESULT GetPrintCapabilities(HPTPROVIDER provider,
+                                      IStream* print_ticket,
+                                      IStream* capabilities,
+                                      BSTR* error_message);
+  static HRESULT ConvertDevModeToPrintTicket(HPTPROVIDER provider,
+                                             ULONG devmode_size_in_bytes,
+                                             PDEVMODE devmode,
+                                             EPrintTicketScope scope,
+                                             IStream* print_ticket);
+  static HRESULT ConvertPrintTicketToDevMode(
+      HPTPROVIDER provider,
+      IStream* print_ticket,
+      EDefaultDevmodeType base_devmode_type,
+      EPrintTicketScope scope,
+      ULONG* devmode_byte_count,
+      PDEVMODE* devmode,
+      BSTR* error_message);
+  static HRESULT MergeAndValidatePrintTicket(HPTPROVIDER provider,
+                                             IStream* base_ticket,
+                                             IStream* delta_ticket,
+                                             EPrintTicketScope scope,
+                                             IStream* result_ticket,
+                                             BSTR* error_message);
+  static HRESULT ReleaseMemory(PVOID buffer);
+  static HRESULT CloseProvider(HPTPROVIDER provider);
+
+ private:
+  XPSModule() {}
+  static bool InitImpl();
+};
+
 // See comments in cc file explaining why we need this.
 class COMPONENT_EXPORT(PRINT_BACKEND) ScopedXPSInitializer {
  public:
@@ -80,7 +125,7 @@
   bool initialized() const { return initialized_; }
 
  private:
-  bool initialized_ = false;
+  bool initialized_;
 };
 
 // Wrapper class to wrap the XPS Print APIs (these are different from the PTxxx
diff --git a/printing/backend/xps_module.cc b/printing/backend/xps_module.cc
deleted file mode 100644
index 713be41..0000000
--- a/printing/backend/xps_module.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2021 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 "printing/backend/xps_module.h"
-
-#include "base/threading/scoped_blocking_call.h"
-
-namespace printing {
-namespace xps_module {
-
-HRESULT OpenProvider(const std::wstring& printer_name,
-                     DWORD version,
-                     HPTPROVIDER* provider) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::MAY_BLOCK);
-  return PTOpenProvider(printer_name.c_str(), version, provider);
-}
-
-HRESULT GetPrintCapabilities(HPTPROVIDER provider,
-                             IStream* print_ticket,
-                             IStream* capabilities,
-                             BSTR* error_message) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::MAY_BLOCK);
-  return PTGetPrintCapabilities(provider, print_ticket, capabilities,
-                                error_message);
-}
-
-HRESULT ConvertDevModeToPrintTicket(HPTPROVIDER provider,
-                                    ULONG devmode_size_in_bytes,
-                                    PDEVMODE devmode,
-                                    EPrintTicketScope scope,
-                                    IStream* print_ticket) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::MAY_BLOCK);
-  return PTConvertDevModeToPrintTicket(provider, devmode_size_in_bytes, devmode,
-                                       scope, print_ticket);
-}
-
-HRESULT ConvertPrintTicketToDevMode(HPTPROVIDER provider,
-                                    IStream* print_ticket,
-                                    EDefaultDevmodeType base_devmode_type,
-                                    EPrintTicketScope scope,
-                                    ULONG* devmode_byte_count,
-                                    PDEVMODE* devmode,
-                                    BSTR* error_message) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::MAY_BLOCK);
-  return PTConvertPrintTicketToDevMode(
-      provider, print_ticket, base_devmode_type, scope, devmode_byte_count,
-      devmode, error_message);
-}
-
-HRESULT MergeAndValidatePrintTicket(HPTPROVIDER provider,
-                                    IStream* base_ticket,
-                                    IStream* delta_ticket,
-                                    EPrintTicketScope scope,
-                                    IStream* result_ticket,
-                                    BSTR* error_message) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::MAY_BLOCK);
-  return PTMergeAndValidatePrintTicket(provider, base_ticket, delta_ticket,
-                                       scope, result_ticket, error_message);
-}
-
-HRESULT ReleaseMemory(PVOID buffer) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::MAY_BLOCK);
-  return PTReleaseMemory(buffer);
-}
-
-HRESULT CloseProvider(HPTPROVIDER provider) {
-  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
-                                                base::BlockingType::MAY_BLOCK);
-  return PTCloseProvider(provider);
-}
-
-}  // namespace xps_module
-}  // namespace printing
diff --git a/printing/backend/xps_module.h b/printing/backend/xps_module.h
deleted file mode 100644
index 339c7e3..0000000
--- a/printing/backend/xps_module.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2021 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 PRINTING_BACKEND_XPS_MODULE_H_
-#define PRINTING_BACKEND_XPS_MODULE_H_
-
-#include <objidl.h>
-#include <prntvpt.h>
-
-#include <string>
-
-namespace printing {
-namespace xps_module {
-
-// Wrappers for the XPS APIs (PTxxx APIs) that annotates the XPS APIs with
-// `base::ScopedBlockingCall`.
-HRESULT OpenProvider(const std::wstring& printer_name,
-                     DWORD version,
-                     HPTPROVIDER* provider);
-HRESULT GetPrintCapabilities(HPTPROVIDER provider,
-                             IStream* print_ticket,
-                             IStream* capabilities,
-                             BSTR* error_message);
-HRESULT ConvertDevModeToPrintTicket(HPTPROVIDER provider,
-                                    ULONG devmode_size_in_bytes,
-                                    PDEVMODE devmode,
-                                    EPrintTicketScope scope,
-                                    IStream* print_ticket);
-HRESULT ConvertPrintTicketToDevMode(HPTPROVIDER provider,
-                                    IStream* print_ticket,
-                                    EDefaultDevmodeType base_devmode_type,
-                                    EPrintTicketScope scope,
-                                    ULONG* devmode_byte_count,
-                                    PDEVMODE* devmode,
-                                    BSTR* error_message);
-HRESULT MergeAndValidatePrintTicket(HPTPROVIDER provider,
-                                    IStream* base_ticket,
-                                    IStream* delta_ticket,
-                                    EPrintTicketScope scope,
-                                    IStream* result_ticket,
-                                    BSTR* error_message);
-HRESULT ReleaseMemory(PVOID buffer);
-HRESULT CloseProvider(HPTPROVIDER provider);
-
-}  // namespace xps_module
-}  // namespace printing
-
-#endif  // PRINTING_BACKEND_XPS_MODULE_H_
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 776c0a1..25efbd17 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -27002,6 +27002,28 @@
         },
         "test": "components_unittests",
         "test_id_prefix": "ninja://components:components_unittests/"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "cpu": "arm64",
+              "inside_docker": "1",
+              "os": "Ubuntu-20.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "unit_tests",
+        "test_id_prefix": "ninja://chrome/test:unit_tests/"
       }
     ]
   },
@@ -28507,6 +28529,28 @@
         },
         "test": "components_unittests",
         "test_id_prefix": "ninja://components:components_unittests/"
+      },
+      {
+        "args": [
+          "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter",
+          "--device=fvdl"
+        ],
+        "merge": {
+          "args": [],
+          "script": "//testing/merge_scripts/standard_gtest_merge.py"
+        },
+        "swarming": {
+          "can_use_on_swarming_builders": true,
+          "dimension_sets": [
+            {
+              "kvm": "1",
+              "os": "Ubuntu-18.04"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "unit_tests",
+        "test_id_prefix": "ninja://chrome/test:unit_tests/"
       }
     ],
     "isolated_scripts": [
diff --git a/testing/buildbot/filters/fuchsia.unit_tests.filter b/testing/buildbot/filters/fuchsia.unit_tests.filter
new file mode 100644
index 0000000..be48d10f
--- /dev/null
+++ b/testing/buildbot/filters/fuchsia.unit_tests.filter
@@ -0,0 +1,116 @@
+-BookmarkBarViewTest.Drop*
+-BookmarkBarViewTest.Mutate*
+-BookmarkMenuDelegateTest.Drop*
+-BrowserReportGeneratorTest.Generate*
+-BrowserUnitTest.DisablePrint*
+-CB*
+-ChromeDownloadManagerDelegateTest.Maybe*
+-ChromePaths.*
+-Chromium/ChannelInfoTest.GetChannel/*
+-ComponentLoaderTest.AddOr*
+-Crash*
+-DeepScanningDownloadTest.LargeFileBlockedByPreference/1
+-DeepScanningDownloadTest.Password*
+-DeepScanningDownloadTest.Policy*
+-DeepScanningDownloadTest.Safe*
+-DeepScanningDownloadTest.UnsupportedFiletypeBlockedByPreference/1
+-DeepScanningUtilsCrash*
+-DevToolsFile*
+-DevToolsUIDataSourceTest.TestDevToolsBundledU*
+-DiagnosticsController*
+-DiagnosticsModelTest.Run*
+-DownloadPrefsTest.AutoOpenPref*
+-DownloadPrefsTest.AutoOpenSetByPolicyDangerous*
+-DownloadPrefsTest.NoAutoOpenByUserForDisallowed*
+-DownloadPrefsTest.Prefs*
+-DownloadPrefsTest.Prerequisites
+-DownloadProtectionServiceFlag*
+-DownloadProtectionServiceTest.Advanced*
+-DownloadProtectionServiceTest.CheckClientDownloadAllowlistedUrl*
+-DownloadProtectionServiceTest.CheckClientDownloadBlob
+-DownloadProtectionServiceTest.CheckClientDownloadData
+-DownloadProtectionServiceTest.CheckClientDownloadDocument*
+-DownloadProtectionServiceTest.CheckClientDownloadFetch*
+-DownloadProtectionServiceTest.CheckClientDownloadH*
+-DownloadProtectionServiceTest.CheckClientDownloadReport*
+-DownloadProtectionServiceTest.CheckClientDownloadSampled*
+-DownloadProtectionServiceTest.CheckClientDownloadSuccess
+-DownloadProtectionServiceTest.CheckClientDownloadValidate*
+-DownloadProtectionServiceTest.CheckClientDownloadZip
+-DownloadProtectionServiceTest.Does*
+-DownloadProtectionServiceTest.E*
+-DownloadProtectionServiceTest.FileSystemAccessWriteRequest_Check*
+-DownloadProtectionServiceTest.FileSystemAccessWriteRequest_Fetch*
+-DownloadProtectionServiceTest.FileSystemAccessWriteRequest_Sampled*
+-DownloadProtectionServiceTest.FileSystemAccessWriteRequest_Success
+-DownloadProtectionServiceTest.FileSystemAccessWriteRequest_Web*
+-DownloadProtectionServiceTest.PPAPIDownloadRequest_Fetch*
+-DownloadProtectionServiceTest.PPAPIDownloadRequest_Invalid*
+-DownloadProtectionServiceTest.PPAPIDownloadRequest_Payload
+-DownloadProtectionServiceTest.PPAPIDownloadRequest_Supported*
+-DownloadProtectionServiceTest.PPAPIDownloadRequest_Timeout
+-DownloadProtectionServiceTest.TestDownloadRequest*
+-DownloadSeparate*
+-Enhanced*
+-EnterpriseCsdDownloadTest.PopulatesCsdFieldWhenEnabled/0
+-EnterpriseCsdDownloadTest.SkipsConsumerCsdWhenEnabled/0
+-EnterpriseHardwarePlatformAPITest.GetHardwarePlatformInfoAllowed
+-ExtensionInstalledBubbleModelTest.Extension*
+-ExtensionProtocolsTest.Resource*
+-ExtensionProtocolsTest.Verification*
+-ExtensionServiceTest.InstallTheme
+-ExtensionUserScriptLoaderTest.Component*
+-ExtensionsMenuViewUnitTest.Invalidate*
+-ExtensionsMenuViewUnitTest.Reorder*
+-ExtensionsMenuViewUnitTest.Reset*
+-ExtensionsMenuViewUnitTest.Run*
+-FileAnalysisRequestTest.Invalid*
+-FileAnalyzerTest.ArchiveIsValidSet*
+-FileAnalyzerTest.Archived*
+-FileAnalyzerTest.Large*
+-FileAnalyzerTest.Rar*
+-FileAnalyzerTest.Small*
+-FileAnalyzerTest.TypeInvalid*
+-FileAnalyzerTest.TypeZipped*
+-FileAnalyzerTest.Zip*
+-FirstRunTest.Initial*
+-FirstRunTest.Legacy*
+-FontAccess*
+-Framework*
+-LastDownloadFinderTest.Add*
+-LastDownloadFinderTest.Simple*
+-LayoutProviderTest.Legacy*
+-MediaEngagementPreloaded*
+-NativeDesktop*
+-Notifications*
+-PermissionMessageCombinationsUnittest.USBSerial*
+-ProfilesState/IsGuestModeRequestedTest.Requested/0
+-ProfilesState/IsGuestModeRequestedTest.Requested/2
+-ProfilesState/IsGuestModeRequestedTest.Requested/4
+-RelaunchNotificationControllerPlatformImplTest.Synchronous*
+-ReportGeneratorTest.Generate*
+-SandboxedRarAnalyzerTest.AnalyzeMultipart*
+-SandboxedRarAnalyzerTest.AnalyzeRarContaining*
+-SandboxedZipAnalyzerTest.One*
+-SandboxedZipAnalyzerTest.Two*
+-SandboxedZipAnalyzerTest.Zipped*
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.Elide/16
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.Elide/18
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.Elide/19
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.Elide/20
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.Elide/22
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.GetLineLengths/16
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.GetLineLengths/18
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.GetLineLengths/19
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.GetLineLengths/20
+-TabHoverCardBubbleViewFilenameEliderGetLineLengthsTest.GetLineLengths/22
+-TaskGroupTest.Shared*
+-TestAccountsUtilTest.GetAccountForPlatform*
+-ThreadWatcherTestWith*
+-ToolbarActionViewUnitTest.Basic*
+-WebAppIconFactoryTest.LoadExact*
+-WebAppIconFactoryTest.LoadIcon*
+-WebAppIconFactoryTest.LoadMaskableIcon
+-WebAppIconFactoryTest.LoadNonMaskableIcon
+-WebAppIconFactoryTest.LoadNonMaskableIcon*
+-WebAppIconFactoryTest.LoadSmall*
diff --git a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter
index 3224c71..15b45da 100644
--- a/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter
+++ b/testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.filter
@@ -2,6 +2,4 @@
 # If you need to disable a tests for version skew, use
 # linux-lacros.lacros_chrome_browsertests.skew.filter.
 
-# TODO(crbug.com/1250611) Re-enable these tests.
--BrowserServiceLacrosBrowserTest.BlockAdditionalWindowsInWebKiosk
 -LacrosExtensionAppsControllerTest.LaunchPinnedApp
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 4d6d9bcf..cd6ca7b 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -1711,6 +1711,11 @@
         ],
       },
       'content_browsertests': {},
+      'unit_tests': {
+        'args': [
+          '--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.unit_tests.filter',
+        ],
+      },
     },
 
     'fuchsia_gpu_telemetry_tests': {
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 392a8c3..b202919 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -7266,21 +7266,6 @@
             ]
         }
     ],
-    "RefactoredNTP": [
-        {
-            "platforms": [
-                "ios"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "RefactoredNTP"
-                    ]
-                }
-            ]
-        }
-    ],
     "RelatedSearches": [
         {
             "platforms": [
@@ -8336,7 +8321,8 @@
                 "chromeos",
                 "linux",
                 "mac",
-                "windows"
+                "windows",
+                "ios"
             ],
             "experiments": [
                 {
diff --git a/third_party/abseil-cpp/absl/flags/BUILD.gn b/third_party/abseil-cpp/absl/flags/BUILD.gn
index a47248b..d2f9f18f 100644
--- a/third_party/abseil-cpp/absl/flags/BUILD.gn
+++ b/third_party/abseil-cpp/absl/flags/BUILD.gn
@@ -114,8 +114,17 @@
   ]
 }
 
+config("absl_flag_internal_config") {
+  if (is_clang) {
+    # TODO(crbug.com/1251757): Figure out what to do with this.
+    cflags = [ "-Wno-unused-value" ]
+  }
+}
+
+
 absl_source_set("flag_internal") {
   sources = [ "internal/flag.cc" ]
+  public_configs = [ ":absl_flag_internal_config" ]
   public = [
     "internal/flag.h",
     "internal/sequence_lock.h",
diff --git a/third_party/blink/renderer/core/BUILD.gn b/third_party/blink/renderer/core/BUILD.gn
index 045bd81..ae36d9d 100644
--- a/third_party/blink/renderer/core/BUILD.gn
+++ b/third_party/blink/renderer/core/BUILD.gn
@@ -1483,6 +1483,7 @@
     "svg/svg_path_query_test.cc",
     "svg/svg_resource_document_content_test.cc",
     "svg/svg_text_content_element_test.cc",
+    "svg/svg_text_element_test.cc",
     "svg/svg_use_element_test.cc",
     "svg/unsafe_svg_attribute_sanitization_test.cc",
     "timing/background_tracing_helper_test.cc",
diff --git a/third_party/blink/renderer/core/layout/layout_inline.h b/third_party/blink/renderer/core/layout/layout_inline.h
index e4c1ea1..b2c07cd 100644
--- a/third_party/blink/renderer/core/layout/layout_inline.h
+++ b/third_party/blink/renderer/core/layout/layout_inline.h
@@ -200,7 +200,7 @@
 
   void AddOutlineRects(Vector<PhysicalRect>&,
                        const PhysicalOffset& additional_offset,
-                       NGOutlineType) const final;
+                       NGOutlineType) const override;
   // The following methods are called from the container if it has already added
   // outline rects for line boxes and/or children of this LayoutInline.
   void AddOutlineRectsForChildrenAndContinuations(
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
index a18898a..a952960 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_items_builder.cc
@@ -271,6 +271,8 @@
 template <typename OffsetMappingBuilder>
 void NGInlineItemsBuilderTemplate<OffsetMappingBuilder>::
     AppendGeneratedBreakOpportunity(LayoutObject* layout_object) {
+  if (block_flow_->IsNGSVGText())
+    return;
   DCHECK(layout_object);
   typename OffsetMappingBuilder::SourceNodeScope scope(&mapping_builder_,
                                                        nullptr);
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
index ae4dc76..70ff8eb 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -829,7 +829,13 @@
         break;
       new_column_block_size = FragmentainerSpaceAtBfcStart(ConstraintSpace());
     } else {
-      DCHECK(minimal_space_shortage != LayoutUnit::Max());
+      // minimal_space_shortage should be set to something meaningful during
+      // layout, but if the column block-size was already "infinite", that's not
+      // possible. We'll then stay at "infinite" block-size and break out of the
+      // loop, since we're not able to get any taller columns.
+      DCHECK(minimal_space_shortage != LayoutUnit::Max() ||
+             column_size.block_size == LayoutUnit::Max());
+
       new_column_block_size = column_size.block_size + minimal_space_shortage;
     }
     new_column_block_size =
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
index 494b105a..ed1c77bb 100644
--- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
+++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
@@ -175,9 +175,6 @@
 
   FloatRect old_boundaries = ObjectBoundingBox();
 
-  // Make sure we don't wrap text.
-  SetOverrideLogicalWidth(LayoutUnit::Max());
-
   UpdateNGBlockLayout();
   needs_update_bounding_box_ = true;
 
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
index 66f9c1a..fdb7f70 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell.h
@@ -76,7 +76,7 @@
   // compat.
   const char* GetName() const final {
     NOT_DESTROYED();
-    return "LayoutNGTableCellNew";
+    return "LayoutNGTableCell";
   }
 
   bool CreatesNewFormattingContext() const final {
diff --git a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell_legacy.h b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell_legacy.h
index ccbb074..541bd5b 100644
--- a/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell_legacy.h
+++ b/third_party/blink/renderer/core/layout/ng/table/layout_ng_table_cell_legacy.h
@@ -28,9 +28,7 @@
 
   void UpdateBlockLayout(bool relayout_children) override;
 
-  // This class used to be called LayoutNGTableCell, and many test baselines
-  // expect its name to be LayoutNGTableCell, not LayoutNGTableCellLegacy.
-  const char* GetName() const override { return "LayoutNGTableCell"; }
+  const char* GetName() const override { return "LayoutNGTableCellLegacy"; }
 
  protected:
   bool IsOfType(LayoutObjectType type) const final {
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
index aae7006..682005f6 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.cc
@@ -162,6 +162,18 @@
   }
 }
 
+void LayoutSVGInline::AddOutlineRects(Vector<PhysicalRect>& rect_list,
+                                      const PhysicalOffset& additional_offset,
+                                      NGOutlineType outline_type) const {
+  if (!IsInLayoutNGInlineFormattingContext()) {
+    LayoutInline::AddOutlineRects(rect_list, additional_offset, outline_type);
+    return;
+  }
+  auto rect = PhysicalRect::EnclosingRect(ObjectBoundingBox());
+  rect.Move(additional_offset);
+  rect_list.push_back(rect);
+}
+
 void LayoutSVGInline::WillBeDestroyed() {
   NOT_DESTROYED();
   SVGResources::ClearClipPathFilterMask(To<SVGElement>(*GetNode()), Style());
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
index 96b6331..9a23b34 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_inline.h
@@ -58,6 +58,9 @@
                           MapCoordinatesFlags) const final;
   void AbsoluteQuads(Vector<FloatQuad>&,
                      MapCoordinatesFlags mode = 0) const final;
+  void AddOutlineRects(Vector<PhysicalRect>&,
+                       const PhysicalOffset& additional_offset,
+                       NGOutlineType) const final;
 
  private:
   InlineFlowBox* CreateInlineFlowBox() final;
diff --git a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
index f96f5c48..2a62433 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_box_fragment_painter.cc
@@ -574,9 +574,16 @@
   }
 
   if (paint_phase == PaintPhase::kForeground) {
+    // NGBoxFragmentPainter::PaintLineBoxChildren() calls
+    // AddURLRectsForInlineChildrenRecursively(). So we don't need to call
+    // AddURLRectIfNeeded() for LayoutInline.
     if (paint_info.ShouldAddUrlMetadata()) {
-      NGFragmentPainter(fragment, GetDisplayItemClient())
-          .AddURLRectIfNeeded(paint_info, paint_offset);
+      const auto* layout_object = fragment.GetLayoutObject();
+      if (!layout_object->IsLayoutInline() ||
+          To<LayoutBoxModelObject>(layout_object)->HasSelfPaintingLayer()) {
+        NGFragmentPainter(fragment, GetDisplayItemClient())
+            .AddURLRectIfNeeded(paint_info, paint_offset);
+      }
     }
     if (is_visible && fragment.HasExtraMathMLPainting())
       NGMathMLPainter(fragment).Paint(paint_info, paint_offset);
diff --git a/third_party/blink/renderer/core/svg/svg_text_element.cc b/third_party/blink/renderer/core/svg/svg_text_element.cc
index e311c65..628e9c4 100644
--- a/third_party/blink/renderer/core/svg/svg_text_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_text_element.cc
@@ -28,8 +28,9 @@
     : SVGTextPositioningElement(svg_names::kTextTag, doc) {}
 
 LayoutObject* SVGTextElement::CreateLayoutObject(const ComputedStyle& style,
-                                                 LegacyLayout legacy) {
-  return LayoutObjectFactory::CreateSVGText(*this, style, legacy);
+                                                 LegacyLayout) {
+  // It's ok to ignore LegacyLayout::kForce because an SVG is never fragmented.
+  return LayoutObjectFactory::CreateSVGText(*this, style, LegacyLayout::kAuto);
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/svg/svg_text_element_test.cc b/third_party/blink/renderer/core/svg/svg_text_element_test.cc
new file mode 100644
index 0000000..ab0b2e2
--- /dev/null
+++ b/third_party/blink/renderer/core/svg/svg_text_element_test.cc
@@ -0,0 +1,28 @@
+// Copyright 2021 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "third_party/blink/renderer/core/page/print_context.h"
+#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h"
+
+namespace blink {
+
+class SVGTextElementTest : public RenderingTest {};
+
+TEST_F(SVGTextElementTest, CreateLayoutObject) {
+  if (!RuntimeEnabledFeatures::LayoutNGEnabled())
+    return;
+  SetBodyInnerHTML(R"HTML(
+      <svg xmlns="http://www.w3.org/2000/svg" width="400" height="400">
+        <text id="t">Foo</text>
+      </svg>)HTML");
+
+  ScopedPrintContext print_context(&GetDocument().View()->GetFrame());
+  print_context->BeginPrintMode(800, 600);
+  const auto* object = GetLayoutObjectByElementId("t");
+  // We use LayoutNGSVGText even in the printing mode, which forces the
+  // legacy layout for now.
+  EXPECT_TRUE(object->IsNGSVGText());
+}
+
+}  // namespace blink
diff --git a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
index b96ec9ef8..28d8030 100644
--- a/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
+++ b/third_party/blink/web_tests/FlagExpectations/disable-layout-ng
@@ -1299,6 +1299,7 @@
 crbug.com/591099 external/wpt/css/css-overflow/scrollable-overflow-input-001.html [ Failure ]
 crbug.com/591099 external/wpt/editing/run/delete.html?7001-last [ Failure ]
 crbug.com/591099 external/wpt/mimesniff/media/media-sniff.window.html [ Failure ]
+crbug.com/591099 external/wpt/editing/other/insert-paragraph-in-void-element.tentative.html [ Failure ]
 
 # inline-end overflow
 crbug.com/1245722 overflow/overflow-basic-002.html [ Failure ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 4ffaade..794a3704b 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2764,7 +2764,7 @@
 crbug.com/1024156 virtual/css-highlight-inheritance/external/wpt/css/css-pseudo/highlight-paired-cascade-006.html [ Pass ]
 crbug.com/1024156 virtual/css-highlight-inheritance/external/wpt/css/css-pseudo/highlight-styling-002.html [ Pass ]
 
-crbug.com/1105958 external/wpt/payment-request/payment-is-showing.https.html [ Skip Timeout Failure ]
+crbug.com/1105958 external/wpt/payment-request/payment-is-showing.https.html [ Failure Skip Timeout ]
 
 ### external/wpt/css/CSS2/tables/
 crbug.com/958381 external/wpt/css/CSS2/tables/column-visibility-004.xht [ Failure ]
@@ -2847,6 +2847,9 @@
 crbug.com/626703 virtual/plz-dedicated-worker/external/wpt/service-workers/service-worker/worker-interception.https.html [ Pass ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 [ Linux ] external/wpt/css/css-flexbox/dynamic-isize-change-002.html [ Crash ]
+crbug.com/626703 external/wpt/css/css-text/tab-size/tab-size-block-ancestor.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-pseudo/highlight-styling-004.html [ Failure ]
 crbug.com/626703 [ Linux ] wpt_internal/webcodecs/basic_video_encoding.https.any.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] wpt_internal/webcodecs/basic_video_encoding.https.any.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/cookies/attributes/domain.sub.html [ Failure ]
@@ -3048,8 +3051,8 @@
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCSctpTransport-maxChannels.html [ Timeout ]
 crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/getstats.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/getstats.html [ Timeout ]
-crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Timeout ]
+crbug.com/626703 [ Mac10.14 ] external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Skip Timeout ]
+crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Skip Timeout ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send.html [ Skip Timeout ]
 crbug.com/626703 [ Mac10.14 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/simplecall.https.html [ Timeout ]
@@ -3143,7 +3146,7 @@
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-helper-test.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/candidate-exchange.https.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/bundle.https.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-getStats.https.html [ Timeout ]
+crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-getStats.https.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-video-frames.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/crypto-suite.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-bufferedAmount.html [ Skip Timeout ]
@@ -3151,19 +3154,19 @@
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCDtlsTransport-getRemoteCertificates.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc-encoded-transform/RTCPeerConnection-insertable-streams-audio.https.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/no-media-call.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Timeout ]
-crbug.com/626703 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Timeout ]
+crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Skip Timeout ]
+crbug.com/626703 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCRtpTransceiver.https.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-close.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-perfect-negotiation.https.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-iceConnectionState.https.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/promises-call.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-createDataChannel.html [ Skip Timeout ]
-crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-addIceCandidate-connectionSetup.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-getStats.https.html [ Timeout ]
-crbug.com/626703 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-getStats.https.html [ Timeout ]
+crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCPeerConnection-addIceCandidate-connectionSetup.html [ Skip Timeout ]
+crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-getStats.https.html [ Skip Timeout ]
+crbug.com/626703 [ Mac11-arm64 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-getStats.https.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/video-rvfc/request-video-frame-callback-webrtc.https.html [ Timeout ]
-crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/rtp-demuxing.html [ Timeout ]
+crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/protocol/rtp-demuxing.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/RTCIceConnectionState-candidate-pair.https.html [ Skip Timeout ]
 crbug.com/626703 [ Mac11.0 ] virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCDataChannel-send-blob-order.html [ Timeout ]
 crbug.com/626703 [ Mac11.0 ] external/wpt/webrtc/simplecall-no-ssrcs.https.html [ Timeout ]
@@ -3222,7 +3225,6 @@
 crbug.com/626703 [ Mac10.15 ] external/wpt/websockets/stream/tentative/constructor.any.html?wpt_flags=h2 [ Failure Timeout ]
 crbug.com/626703 [ Win ] external/wpt/websockets/stream/tentative/constructor.any.html?wpt_flags=h2 [ Failure Timeout ]
 crbug.com/626703 [ Win ] external/wpt/websockets/stream/tentative/backpressure-send.any.html?wpt_flags=h2 [ Failure Skip Timeout ]
-crbug.com/626703 [ Mac10.15 ] external/wpt/websockets/basic-auth.any.sharedworker.html?wpt_flags=h2 [ Crash Failure Timeout ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/webrtc-encoded-transform/script-metadata-transform.https.html [ Failure Timeout ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/fetch/api/basic/request-upload.any.serviceworker.html [ Crash Failure Timeout ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/editing/other/editing-around-select-element.tentative.html?insertText [ Crash Failure Skip Timeout ]
@@ -3244,14 +3246,12 @@
 crbug.com/626703 virtual/plz-dedicated-worker/external/wpt/html/cross-origin-embedder-policy/multi-globals/workers-coep-report.https.html [ Failure Pass ]
 crbug.com/626703 [ Mac10.15 ] virtual/plz-dedicated-worker/external/wpt/fetch/api/basic/http-response-code.any.html [ Crash Failure ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/fetch/api/basic/http-response-code.any.sharedworker.html [ Crash Failure ]
-crbug.com/626703 [ Mac10.15 ] external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker.html?wpt_flags=h2 [ Crash Failure ]
 crbug.com/626703 [ Mac ] external/wpt/FileAPI/file/send-file-formdata-controls.html [ Crash Failure ]
 crbug.com/626703 [ Win ] external/wpt/FileAPI/file/send-file-formdata-controls.html [ Crash Failure ]
 crbug.com/626703 [ Mac ] external/wpt/websockets/stream/tentative/abort.any.serviceworker.html?wpt_flags=h2 [ Crash Failure Pass ]
 crbug.com/626703 [ Mac10.15 ] external/wpt/websockets/stream/tentative/abort.any.sharedworker.html?wpt_flags=h2 [ Crash Failure ]
 crbug.com/626703 [ Mac10.12 ] external/wpt/websockets/stream/tentative/backpressure-send.any.html?wpt_flags=h2 [ Failure Skip Timeout ]
 crbug.com/626703 [ Mac10.13 ] external/wpt/websockets/stream/tentative/backpressure-send.any.html?wpt_flags=h2 [ Failure Skip Timeout ]
-crbug.com/626703 [ Mac10.15 ] external/wpt/websockets/stream/tentative/backpressure-send.any.worker.html?wpt_flags=h2 [ Crash Failure ]
 crbug.com/626703 [ Mac10.15 ] virtual/offsetparent-old-behavior/external/wpt/shadow-dom/accesskey.tentative.html [ Crash Failure ]
 crbug.com/626703 external/wpt/websockets/stream/tentative/close.any.html?wpt_flags=h2 [ Failure Timeout ]
 crbug.com/626703 external/wpt/websockets/stream/tentative/close.any.sharedworker.html?wpt_flags=h2 [ Failure Timeout ]
@@ -4900,9 +4900,6 @@
 # Sheriff 2019-06-05
 crbug.com/971259 media/controls/volumechange-stopimmediatepropagation.html [ Failure Pass ]
 
-# Sheriff 2019-06-20
-crbug.com/976045 fast/scrolling/unscrollable-layer-subpixel-size-with-negative-overflow.html [ Failure Pass ]
-
 crbug.com/974710 [ Win7 ] http/tests/security/isolatedWorld/bypass-main-world-csp-iframes.html [ Failure Pass ]
 
 # Expected new failures until crbug.com/535738 is fixed. The failures also vary
@@ -5714,7 +5711,7 @@
 crbug.com/1138591 [ Mac10.15 ] http/tests/dom/raf-throttling-out-of-view-cross-origin-page.html [ Failure ]
 
 # WebRTC: Payload demuxing times out in Plan B. This is expected.
-crbug.com/1139052 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/rtp-demuxing.html [ Timeout ]
+crbug.com/1139052 virtual/webrtc-wpt-plan-b/external/wpt/webrtc/protocol/rtp-demuxing.html [ Skip Timeout ]
 
 crbug.com/1137228 [ Mac ] external/wpt/infrastructure/testdriver/click_iframe_crossorigin.sub.html [ Failure Pass ]
 
@@ -6862,7 +6859,7 @@
 crbug.com/1249176 [ Mac11-arm64 ] external/wpt/focus/focus-already-focused-iframe-same-site.html [ Timeout ]
 crbug.com/1249176 [ Mac11-arm64 ] external/wpt/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/location-setter-user-mouseup.html [ Failure Timeout ]
 crbug.com/1249176 [ Mac11-arm64 ] external/wpt/selection/textcontrols/selectionchange-bubble.html [ Timeout ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Timeout Failure Skip ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-paint/paint-profiler-update.js [ Failure Skip Timeout ]
 
 # Flaky tests in mac11-arm64
 crbug.com/1249176 [ Mac11-arm64 ] transforms/3d/general/cssmatrix-3d-zoom.html [ Failure Pass ]
@@ -6871,30 +6868,30 @@
 crbug.com/1249176 [ Mac11-arm64 ] fast/forms/plaintext-mode-2.html [ Failure Pass ]
 crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-image-canvas.html [ Failure Pass ]
 crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/jpeg-with-color-profile.html [ Failure Pass ]
-crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-background-image-repeat.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-image-shape.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/console/console-time.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/console-timeline.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/inspector-protocol/runtime/eval-await-navigation-paused-message-order.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] inspector-protocol/timeline/timeline-layout.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/2-comp.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-time/timeline-usertiming.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] external/wpt/resource-timing/nested-context-navigations-embed.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] fast/block/float/float-on-clean-line-subsequently-dirtied.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-js/timeline-microtasks.js [ Pass Failure ]
+crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-background-image-repeat.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-image-shape.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/console/console-time.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/console-timeline.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/inspector-protocol/runtime/eval-await-navigation-paused-message-order.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] inspector-protocol/timeline/timeline-layout.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/2-comp.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-time/timeline-usertiming.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] external/wpt/resource-timing/nested-context-navigations-embed.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] fast/block/float/float-on-clean-line-subsequently-dirtied.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-js/timeline-microtasks.js [ Failure Pass ]
 crbug.com/1249176 [ Mac11-arm64 ] http/tests/intersection-observer/cross-origin-iframe-with-nesting.html [ Pass Timeout ]
-crbug.com/1249176 [ Mac11-arm64 ] media/controls/overflow-menu-always-visible.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] paint/markers/document-markers-font-8px.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] paint/markers/document-markers-zoom-2000.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-layout/timeline-layout-reason.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] external/wpt/resource-timing/nested-context-navigations-object.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] external/wpt/webvtt/rendering/cues-with-video/processing-model/audio_has_no_subtitles.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] virtual/synchronous_html_parser/http/tests/preload/without_doc_write_evaluator.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/elements/accessibility/edit-aria-attributes.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] inspector-protocol/overlay/overlay-persistent-overlays-with-emulation.js [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] virtual/scroll-unification/plugins/multiple-plugins.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-animate.html [ Pass Failure ]
-crbug.com/1249176 [ Mac11-arm64 ] fast/layers/clip-rects-transformed-2.html [ Pass Failure ]
+crbug.com/1249176 [ Mac11-arm64 ] media/controls/overflow-menu-always-visible.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] paint/markers/document-markers-font-8px.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] paint/markers/document-markers-zoom-2000.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/tracing/timeline-layout/timeline-layout-reason.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] external/wpt/resource-timing/nested-context-navigations-object.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] external/wpt/webvtt/rendering/cues-with-video/processing-model/audio_has_no_subtitles.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] virtual/synchronous_html_parser/http/tests/preload/without_doc_write_evaluator.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] http/tests/devtools/elements/accessibility/edit-aria-attributes.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] inspector-protocol/overlay/overlay-persistent-overlays-with-emulation.js [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] virtual/scroll-unification/plugins/multiple-plugins.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] virtual/gpu-rasterization/images/color-profile-animate.html [ Failure Pass ]
+crbug.com/1249176 [ Mac11-arm64 ] fast/layers/clip-rects-transformed-2.html [ Failure Pass ]
 crbug.com/1249176 [ Mac11-arm64 ] external/wpt/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/location-setter-user-click.html [ Failure Timeout ]
 
 
@@ -6961,3 +6958,7 @@
 crbug.com/1250534 virtual/file-system-access-access-handle-incognito/external/wpt/file-system-access/sandboxed_FileSystemDirectoryHandle-rename.https.any.html [ Failure ]
 crbug.com/1250534 virtual/file-system-access-access-handle-incognito/external/wpt/file-system-access/sandboxed_FileSystemDirectoryHandle-move.https.any.worker.html [ Failure ]
 crbug.com/1250534 virtual/file-system-access-access-handle-incognito/external/wpt/file-system-access/sandboxed_FileSystemDirectoryHandle-rename.https.any.worker.html [ Failure ]
+
+# Sheriff 2021-09-23
+crbug.com/1164568 [ Mac10.12 ] external/wpt/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html [ Failure ]
+crbug.com/1164568 [ Mac10.13 ] external/wpt/html/cross-origin-opener-policy/reporting/navigation-reporting/reporting-popup-same-origin-allow-popups-report-to.https.html [ Failure ]
diff --git a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
index b558cbd..ed62d5d 100644
--- a/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
+++ b/third_party/blink/web_tests/android/WebLayerWPTOverrideExpectations
@@ -821,6 +821,7 @@
 crbug.com/1050754 external/wpt/external/wpt/streams/piping/pipe-through.any.html [ Failure ]
 crbug.com/1050754 external/wpt/external/wpt/streams/piping/pipe-through.any.sharedworker.html [ Failure ]
 crbug.com/1050754 external/wpt/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html [ Timeout ]
+crbug.com/1050754 external/wpt/external/wpt/webrtc/protocol/rtp-demuxing.html [ Failure ]
 crbug.com/1050754 external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Failure ]
 crbug.com/1050754 external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy-attribute.https.sub.html [ Failure ]
 crbug.com/1050754 external/wpt/feature-policy/picture-in-picture-allowed-by-feature-policy.https.sub.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 3553f44..72ffa06 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -611,6 +611,13 @@
      ]
     },
     "css-inline": {
+     "inline-002-crash.html": [
+      "a10eee9907f3ca27b3265452aeb19e2b9710b55d",
+      [
+       null,
+       {}
+      ]
+     ],
      "inline-crash.html": [
       "65008f74ce6e0b4397a5b333099c692382d64353",
       [
@@ -1643,6 +1650,13 @@
        {}
       ]
      ],
+     "inserthorizontalrule-in-fieldset-and-everything-styled-white-space-pre.html": [
+      "d06157e78429b9365f5122180426f46b96785b96",
+      [
+       null,
+       {}
+      ]
+     ],
      "inserthtml-in-inline-editing-host-at-load-event.html": [
       "22f172856adc852499478cccaca685cd4d49f837",
       [
@@ -1678,6 +1692,13 @@
        {}
       ]
      ],
+     "justifyfull-selection-containing-non-editable-div-and-everything-styled-white-space-break-space.html": [
+      "cf199fa087eadd205bcd4bebb93d56cbe139286c",
+      [
+       null,
+       {}
+      ]
+     ],
      "make-parent-element-editable-after-making-focused-editing-host-non-editable.html": [
       "d624d7d3b98a7c615951f10e381e99fb1266c424",
       [
@@ -2496,28 +2517,28 @@
    "appmanifest": {
     "display-member": {
      "display-member-media-feature-browser-manual.html": [
-      "e568cc538abf46056b9ceb745286228805bc60b6",
+      "690b4ba521be0d5e3c90b6570b7c6725d3347cab",
       [
        null,
        {}
       ]
      ],
      "display-member-media-feature-fullscreen-manual.html": [
-      "77f41b0a5a9f2906f6a5ce84841cd7b5e1b6ae20",
+      "a6db66679c97b834f60be8258827231a0f81cb31",
       [
        null,
        {}
       ]
      ],
      "display-member-media-feature-minimal-ui-manual.html": [
-      "b0a67d7867a8e8aa953d98797db6b1c7e7372c43",
+      "b645d6cd7fdc93c5eb87850e6326dce9f8d0542b",
       [
        null,
        {}
       ]
      ],
      "display-member-media-feature-standalone-manual.html": [
-      "b62007b7ae6872de0561c08f903756a0a104a413",
+      "c820091f0f93dc248b4784ff8968eae685c75da7",
       [
        null,
        {}
@@ -2562,8 +2583,8 @@
      ]
     },
     "file_handlers-member": {
-     "file_handlers-member-manual.html": [
-      "b44fa8264a1ced31bc22fcc18d58b7c43e1bbf57",
+     "file_handlers-member-manual.tentative.html": [
+      "f6384b6dda33e088d94b8a47168f2ca1fee9698a",
       [
        null,
        {}
@@ -9684,13 +9705,6 @@
       {}
      ]
     ],
-    "local_FileSystemBaseHandle-move-manual.https.html": [
-     "2290a3144dae31cf1a8998bb491254d446478531",
-     [
-      null,
-      {}
-     ]
-    ],
     "local_FileSystemBaseHandle-postMessage-BroadcastChannel-manual.https.html": [
      "f395b0b4c17e18ac36e835c0c39576f3fe30525c",
      [
@@ -9754,13 +9768,6 @@
       {}
      ]
     ],
-    "local_FileSystemBaseHandle-rename-manual.https.html": [
-     "e3e5305320cf53fc10772d8ba5befead5b94e9ea",
-     [
-      null,
-      {}
-     ]
-    ],
     "local_FileSystemDirectoryHandle-getDirectoryHandle-manual.https.html": [
      "63a88538e8b915e80d334949ca2b2b619d3e9654",
      [
@@ -9782,6 +9789,13 @@
       {}
      ]
     ],
+    "local_FileSystemDirectoryHandle-move-manual.https.html": [
+     "20c6ccfdebd915c6db4854b60ffa8ca1cb43e90a",
+     [
+      null,
+      {}
+     ]
+    ],
     "local_FileSystemDirectoryHandle-removeEntry-manual.https.html": [
      "765492e1e861779567df9f255628eb0f5ffb83df",
      [
@@ -9789,6 +9803,13 @@
       {}
      ]
     ],
+    "local_FileSystemDirectoryHandle-rename-manual.https.html": [
+     "a4a7fb9b5985e08e7f03701033dfe35c17ebfb0b",
+     [
+      null,
+      {}
+     ]
+    ],
     "local_FileSystemDirectoryHandle-resolve-manual.https.html": [
      "0d539abb54e08f8bfbb06bcc5010cda3a53b83da",
      [
@@ -9810,6 +9831,20 @@
       {}
      ]
     ],
+    "local_FileSystemFileHandle-move-manual.https.html": [
+     "3d056a507966902fc59e3e327cc53c09f0eabc14",
+     [
+      null,
+      {}
+     ]
+    ],
+    "local_FileSystemFileHandle-rename-manual.https.html": [
+     "66771018dddac930cd696228c4ae3302f8001b05",
+     [
+      null,
+      {}
+     ]
+    ],
     "local_FileSystemWritableFileStream-manual.https.html": [
      "2db242c708d029893cea4294af15f5b751716fe1",
      [
@@ -77069,6 +77104,19 @@
        {}
       ]
      ],
+     "br-clear-all.html": [
+      "ac3a67ffd034ecb315c66da5682500dea47ee2d4",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "break-at-end-container-edge-000.html": [
       "4836f399de4fc8af657ff7729215ee7e89054798",
       [
@@ -77420,6 +77468,19 @@
        {}
       ]
      ],
+     "fieldset-007.html": [
+      "37bd1ac2e58275e97a4f31f1b89a4ae50aea7ae9",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square-only.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "fieldset.html": [
       "fe76988293b8d1d9a6226b23bb9b40e86fcc007a",
       [
@@ -77526,6 +77587,71 @@
        ]
       ]
      },
+     "float-000.html": [
+      "36a0722805edf73793d20c1739379123d89c698e",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "float-001.html": [
+      "84b238a7c6d1e8d874b48ae2c7d1573f06c4f5ca",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "float-002.html": [
+      "e1036b0ce8bf31b21cc815d93c2fbed614cdb6fc",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "float-003.html": [
+      "1d1bd37bbf5a06e5562bbe8e207fefb5c67a2644",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "float-004.html": [
+      "f2fce78175e43cd29b5ab4615bfeeca6c4ea97d7",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "float-in-self-collapsing-block-000.html": [
       "e42d941e78ab45e9107ac49ee8c8c2b4c6d43c9d",
       [
@@ -78865,6 +78991,19 @@
        {}
       ]
      ],
+     "overflow-clip-012.html": [
+      "0038ce3235eed5d8f6ad0ddafcd6436d0dee966c",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square-only.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "overflowed-block-with-no-room-after-000.html": [
       "084e16fb38de072fb83f92ba01302a2e404cdd97",
       [
@@ -92990,13 +93129,52 @@
        {}
       ]
      ],
-     "dynamic-isize-change.html": [
-      "5d3bc99a322c294a71bd676679200de87c5129ad",
+     "dynamic-isize-change-001.html": [
+      "cf4a03004398457bcc59471ef54138442247144b",
       [
        null,
        [
         [
-         "/css/css-flexbox/dynamic-isize-change-ref.html",
+         "/css/css-flexbox/dynamic-isize-change-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "dynamic-isize-change-002.html": [
+      "cc859b73f9ae9406d6a00713ca645c1c0493ed23",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "dynamic-isize-change-003.html": [
+      "9df13e313fda0b32a827f67432972ec3d73240b3",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "dynamic-isize-change-004.html": [
+      "1627e32d966d92610ffd2577abf42a72a16a8cf7",
+      [
+       null,
+       [
+        [
+         "/css/reference/ref-filled-green-100px-square.xht",
          "=="
         ]
        ],
@@ -132997,7 +133175,7 @@
       ]
      ],
      "active-selection-012.html": [
-      "e4e291f92a225c623b43748dda6a20f54c5e8fe6",
+      "d1612ece0f404d070e21cc54799ca363781f6e32",
       [
        null,
        [
@@ -133932,6 +134110,32 @@
        {}
       ]
      ],
+     "highlight-cascade-001.html": [
+      "f237e9eca7321123c6d9de5f40cd95a5cab62fc9",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-cascade-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-cascade-002.html": [
+      "c01d3c796e5ec88c16dae4c1819908a03cba4078",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-cascade-002-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "highlight-painting-001.html": [
       "ef253e6117c94ef63f9be97eaac0d94667c9fce3",
       [
@@ -133992,6 +134196,136 @@
        {}
       ]
      ],
+     "highlight-paired-cascade-001.html": [
+      "09e5abf9a3285ff219044a84b61bbc239f405689",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-paired-cascade-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-paired-cascade-002.html": [
+      "affbe9562975c351f848bdc927c1cdcc56e118f5",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-paired-cascade-002-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-paired-cascade-003.html": [
+      "250e320210c65f6b8538adf849362d5e34da634a",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-paired-cascade-003-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-paired-cascade-004.tentative.html": [
+      "cc1d4daa971b65bc861f1b3c67b7c5523dba867b",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-paired-cascade-004-notref.html",
+         "!="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-paired-cascade-005.tentative.html": [
+      "4d402292eb5ff7238c174a151df5bfb59b3a57b8",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-paired-cascade-005-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-paired-cascade-006.html": [
+      "20c03282c81a03df93d912080ede2bb5fc8e64ed",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-paired-cascade-006-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-styling-001.html": [
+      "63d8ee1eda47dec0eeaf30f56316e4203e49f182",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-styling-001-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-styling-002.html": [
+      "2f7cc29128e4dc8de7922922f33cab8451c0eaf1",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-styling-002-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-styling-003.html": [
+      "803b44011863e1ab065be21d1d7aa693255c8119",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-styling-003-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
+     "highlight-styling-004.html": [
+      "28d5bc01fad7b353b60f56c0f226f519bb2102f2",
+      [
+       null,
+       [
+        [
+         "/css/css-pseudo/highlight-styling-004-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "highlight-z-index-001.html": [
       "f81d25ceb9d2e4199ad80f827bd27b34013701fc",
       [
@@ -151464,6 +151798,19 @@
         {}
        ]
       ],
+      "tab-size-block-ancestor.html": [
+       "b295382a2f1d6f19c340d5b3ec367ea01e0c29e4",
+       [
+        null,
+        [
+         [
+          "/css/css-text/tab-size/tab-size-block-ancestor-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "tab-size-inheritance-001.html": [
        "0cba27079bdccf650774da9f445f18e5eb659918",
        [
@@ -171307,6 +171654,19 @@
        {}
       ]
      ],
+     "appearance-auto-non-html-namespace-001.html": [
+      "892e0da63bb54dc9e5af6af31dd8ad3ec18f59a3",
+      [
+       null,
+       [
+        [
+         "/css/css-ui/nothing-below-ref.html",
+         "=="
+        ]
+       ],
+       {}
+      ]
+     ],
      "appearance-button-001.html": [
       "317f56b18ae7109962340f3364d06d7116f97077",
       [
@@ -197518,6 +197878,32 @@
           ],
           {}
          ]
+        ],
+        "imageBitmapRendering-transferFromImageBitmap-flipped.html": [
+         "02e0690876430b8c746cca4bee19d39e11836df9",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-flipped-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
+        ],
+        "imageBitmapRendering-transferFromImageBitmap.html": [
+         "d615583c0d5699d318b681d30224b7e3fdc41f6f",
+         [
+          null,
+          [
+           [
+            "/html/canvas/element/manual/imagebitmap/imageBitmapRendering-transferFromImageBitmap-expected.html",
+            "=="
+           ]
+          ],
+          {}
+         ]
         ]
        },
        "line-styles": {
@@ -201949,7 +202335,7 @@
         ]
        ],
        "image-loading-lazy-slow-aspect-ratio.html": [
-        "2d302970cab98fa13cd5653c025003286efb7b29",
+        "662ada69095c5079924008ad2a252fdaa474267e",
         [
          null,
          [
@@ -201962,7 +202348,7 @@
         ]
        ],
        "image-loading-lazy-slow.html": [
-        "a972100528360511b93dcdc42fa0f596142ec2e2",
+        "fac2c2e8f742b6ee83fc9f3447c8fe9abfd7ad5c",
         [
          null,
          [
@@ -214097,38 +214483,52 @@
      []
     ],
     "display-member": {
-     "display-member-media-feature-browser.webmanifest": [
-      "1b633378ad49a20434a4eca619bde612d660a958",
+     "display-member-media-feature-service-worker.js": [
+      "5720e3cbc3fa317677c36c95f0aa2d0bb3c544cd",
       []
      ],
-     "display-member-media-feature-browser.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "display-member-media-feature-fullscreen.webmanifest": [
-      "a39466df1ac15bf41a80ed1e8ffe70838d40e7e7",
-      []
-     ],
-     "display-member-media-feature-fullscreen.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "display-member-media-feature-minimal-ui.webmanifest": [
-      "471f5d5d5d0bc3387d964260f7354908ad997b7a",
-      []
-     ],
-     "display-member-media-feature-minimal-ui.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ],
-     "display-member-media-feature-standalone.webmanifest": [
-      "891bd79fbfe119c185a3dc5606063eeda60ccc47",
-      []
-     ],
-     "display-member-media-feature-standalone.webmanifest.headers": [
-      "2bab061d43ab9e533b0160ca506231939886cd89",
-      []
-     ]
+     "resources": {
+      "display-member-media-feature-browser.webmanifest": [
+       "9e1f6a335066e762de581391e43ae39a11452fde",
+       []
+      ],
+      "display-member-media-feature-browser.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "display-member-media-feature-fullscreen.webmanifest": [
+       "3954538e508c6cec52c4e69f4354230468d39e52",
+       []
+      ],
+      "display-member-media-feature-fullscreen.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "display-member-media-feature-manual.js": [
+       "60723d5afea115668279c22bb1374dcbbd384c33",
+       []
+      ],
+      "display-member-media-feature-minimal-ui.webmanifest": [
+       "9463941aa489d7f9a1952b678b90ec1656bdf0aa",
+       []
+      ],
+      "display-member-media-feature-minimal-ui.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "display-member-media-feature-standalone.webmanifest": [
+       "a8269e977c426ae692fb2540821314d16988168b",
+       []
+      ],
+      "display-member-media-feature-standalone.webmanifest.headers": [
+       "2bab061d43ab9e533b0160ca506231939886cd89",
+       []
+      ],
+      "icon.png": [
+       "267cba8d1eed9aa5f9606ae850d20f9d335da975",
+       []
+      ]
+     }
     },
     "display-override-member": {
      "display-override-member-media-feature-browser.webmanifest": [
@@ -214173,17 +214573,17 @@
      ]
     },
     "file_handlers-member": {
-     "file_handlers-member-manual-service-worker.js": [
-      "6978894f31169d700ebe704de5d5ab5377c65143",
+     "file_handlers-member-service-worker.js": [
+      "972b65304b57600a22258b4133283962e780adb2",
       []
      ],
      "resources": {
-      "file_handlers-member-manual.js": [
-       "94b24262b92021177bf6f8fc682453e5db1137e8",
+      "file_handlers-member.js": [
+       "87ec82ef9a7e53785e73222ec77b9254beb4bd40",
        []
       ],
-      "file_handlers-member-manual.webmanifest": [
-       "6386463948a34ee4ba44bdd653e8f59bfebc29eb",
+      "file_handlers-member.webmanifest": [
+       "1cc5bf4aa9df076697ce9bf86d5d5f7e2878f13e",
        []
       ],
       "file_handlers-sample-file.txt": [
@@ -214701,7 +215101,7 @@
      []
     ],
     "README.md": [
-     "abe277712bc41d1d5f70a08d09e2e09945a156ab",
+     "8d0f063db02e1950b2ea19cb8dfc59128e081dc2",
      []
     ],
     "generate.py": [
@@ -215531,7 +215931,7 @@
        []
       ],
       "stylesheet.py": [
-       "29079af922894a3ae052a807f269dde23fbfde4c",
+       "05db249250dad9a1544c654560de459b0262a2ed",
        []
       ],
       "subresource.py": [
@@ -226023,17 +226423,13 @@
        []
       ],
       "background-image-interpolation-expected.txt": [
-       "0d58012bada5a4860f1ba038b0a33f5d0f977318",
+       "0101057a5722f23b71bb360676cc45ea2a81fe3e",
        []
       ],
       "border-image-source-interpolation-expected.txt": [
        "f11069c94c040f4e1fa2b75a67f9f750e90f480d",
        []
       ],
-      "box-shadow-interpolation-expected.txt": [
-       "8ffcb3b011de256b1d5d4c546ad1b75542fd9b59",
-       []
-      ],
       "invalidation": {
        "background-color-animation-with-zero-alpha-ref.html": [
         "8442d3de965d939504d7ac059203d0eabbec9a6a",
@@ -230679,7 +231075,7 @@
       "b8db7ea2c7de6443075e04009ff5c979dbb7fed3",
       []
      ],
-     "dynamic-isize-change-ref.html": [
+     "dynamic-isize-change-001-ref.html": [
       "58b34c43feec25b962ecb906665bcaac7aee1dc2",
       []
      ],
@@ -233406,7 +233802,7 @@
       []
      ],
      "inheritance-expected.txt": [
-      "7bd2069e299d14a7f95890934c35e243af5a351a",
+      "68cc145db7dc3856612d22dd001ab0342b030785",
       []
      ],
      "line-gap-override-ref.html": [
@@ -233500,6 +233896,14 @@
        "2d88f5719bf349c9b7db5725b06215f66f9748a8",
        []
       ],
+      "font-palette-values-invalid-expected.txt": [
+       "2d11c5443961f1f6a288603912f6c2867175b1e3",
+       []
+      ],
+      "font-palette-values-valid-expected.txt": [
+       "d8f9ffbb55ae057e1ee3e637bb19e1bce1a46cfe",
+       []
+      ],
       "font-size-adjust-computed-expected.txt": [
        "c824213e0a9e82e61b31deac83c0dcdaecc30276",
        []
@@ -233512,14 +233916,6 @@
        "ad92993bc0f0263cd0261f2ecfa28f7b2c149bd0",
        []
       ],
-      "font-synthesis-computed-expected.txt": [
-       "07c56a9473bbb91705b12fa5f5a5b4a0f99ae72e",
-       []
-      ],
-      "font-synthesis-valid-expected.txt": [
-       "79a68a03af8625314d8fd8cd90dcec4d7c339bc4",
-       []
-      ],
       "font-variant-position-computed-expected.txt": [
        "bf89a6a1596c067ac6bccb00fca97bd682081cce",
        []
@@ -245711,6 +246107,14 @@
       "ecdb308f2f426af4f2763fabb30f7244f42fcf62",
       []
      ],
+     "highlight-cascade-001-ref.html": [
+      "a18690962fcd4e73d5832f76e7afb8ee681ae24e",
+      []
+     ],
+     "highlight-cascade-002-ref.html": [
+      "17629a6dbad7fb5700b35b8bd0ea5280dba69140",
+      []
+     ],
      "highlight-painting-001-ref.html": [
       "c5d8814a8252b0a8e4be1b43f635cd7b11f548fc",
       []
@@ -245735,6 +246139,46 @@
       "732f6bfe0dbfe2be32bfa225e53c1da84fa8a98b",
       []
      ],
+     "highlight-paired-cascade-001-ref.html": [
+      "14687acb841d2b85becead81a0c82b4e4b5b8e9d",
+      []
+     ],
+     "highlight-paired-cascade-002-ref.html": [
+      "48eb9911a104c7b74bbafaefbe19cd23c3ce5d7f",
+      []
+     ],
+     "highlight-paired-cascade-003-ref.html": [
+      "18885fdc898a4ccc260db6056f7c102ffd661c69",
+      []
+     ],
+     "highlight-paired-cascade-004-notref.html": [
+      "63472b67589c2b2bfd1c74d40b3dd0974e1a0e83",
+      []
+     ],
+     "highlight-paired-cascade-005-ref.html": [
+      "0ac5c02b203bc0b84438e960cd5d015e47303982",
+      []
+     ],
+     "highlight-paired-cascade-006-ref.html": [
+      "18885fdc898a4ccc260db6056f7c102ffd661c69",
+      []
+     ],
+     "highlight-styling-001-ref.html": [
+      "0ea90d7434d546193065b2fe58e8da5f5ae58f8c",
+      []
+     ],
+     "highlight-styling-002-ref.html": [
+      "0ea90d7434d546193065b2fe58e8da5f5ae58f8c",
+      []
+     ],
+     "highlight-styling-003-ref.html": [
+      "0ea90d7434d546193065b2fe58e8da5f5ae58f8c",
+      []
+     ],
+     "highlight-styling-004-ref.html": [
+      "0ea90d7434d546193065b2fe58e8da5f5ae58f8c",
+      []
+     ],
      "highlight-z-index-001-ref.html": [
       "0e9f9c252b2244f7ba0a33aaccf9cf0c12420e4c",
       []
@@ -245971,7 +246415,7 @@
        []
       ],
       "active-selection-012-ref.html": [
-       "5f45e50952ea590930b33b0e72c6bb5d88095a14",
+       "d212344c1292b9a9e297795ac3670610972c9700",
        []
       ],
       "active-selection-014-ref.html": [
@@ -248796,26 +249240,6 @@
        "b3d3fc34d5c2622d011b6c3286c34eb930a33f75",
        []
       ],
-      "ja": {
-       "css-text-line-break-ja-in-loose-expected.txt": [
-        "4c1a998dc6c33295962be7d65c3ef5bfe22c7491",
-        []
-       ],
-       "css-text-line-break-ja-pr-normal-expected.txt": [
-        "8432cf1ffb6a716e11d77e993f123612b498e224",
-        []
-       ],
-       "css-text-line-break-ja-pr-strict-expected.txt": [
-        "5319ad190fff29199d6acb9710202b4a1d62654a",
-        []
-       ]
-      },
-      "other-lang": {
-       "css-text-line-break-de-in-loose-expected.txt": [
-        "ee73f7ade4d85d0d6ede09bccc1730dc28f4cf2d",
-        []
-       ]
-      },
       "reference": {
        "css3-text-line-break-opclns-001-ref.html": [
         "d3827a52989d4d5f0f7f5f8bb625be19c5ace3a0",
@@ -249538,29 +249962,11 @@
       },
       "unknown-lang": {
        "css-text-line-break-cj-strict-expected.txt": [
-        "5fa18c5ac8e5dae7292d3753fd57708dbf1ae197",
-        []
-       ],
-       "css-text-line-break-in-loose-expected.txt": [
-        "c41356766695fb85dc5cadf97d17a476701c4d56",
+        "34159edcecf19f0ce06840be497dd24e9c4d5785",
         []
        ],
        "css-text-line-break-iteration-loose-expected.txt": [
-        "6d7a0fb56fb790fb3c7bffbe0ffe694f3bd3ada9",
-        []
-       ]
-      },
-      "zh": {
-       "css-text-line-break-zh-in-loose-expected.txt": [
-        "ec0cad2a45926d12790088d0d332b66ec4afea0f",
-        []
-       ],
-       "css-text-line-break-zh-pr-normal-expected.txt": [
-        "0dd73724bc8e965af574ffe654313cd80cdea70f",
-        []
-       ],
-       "css-text-line-break-zh-pr-strict-expected.txt": [
-        "5d9d42c59ec0507bfdaf769cfe3db1a952a40c62",
+        "4a37e5d674c62c8a272a4dd4e79fe95b19e831ac",
         []
        ]
       }
@@ -250314,6 +250720,10 @@
        "7623adb59e65bed4787a9105ce54caa8fed63fa8",
        []
       ],
+      "tab-size-block-ancestor-ref.html": [
+       "bb1cdc93a3f300138ce68dcd4354b3fafb7ba98b",
+       []
+      ],
       "tab-size-inheritance-001-ref.html": [
        "5e253df9490e5182dde59a23077815a2176583ee",
        []
@@ -252255,21 +252665,13 @@
        []
       ],
       "rotate-composition-expected.txt": [
-       "6c4d6399d0f01f4939ea36744460578bf673dcaa",
-       []
-      ],
-      "rotate-interpolation-expected.txt": [
-       "97158b5f8c8ce149b28df2c87aa93e52dd8c1a99",
+       "ed01489819048567b3704f630d6ae77f3be1657d",
        []
       ],
       "rotate-transform-equivalent-ref.html": [
        "e95e62be888216d9bcd2487c54c1da602973de75",
        []
       ],
-      "scale-interpolation-expected.txt": [
-       "05b835c0dce6b10915040dfab647df818dd10d40",
-       []
-      ],
       "support": {
        "transform-interpolation-reftests.js": [
         "ba071696be22eaf348eb4ccacec8638be048d85e",
@@ -252277,7 +252679,7 @@
        ]
       },
       "transform-interpolation-001-expected.txt": [
-       "98ab37b42459130e9834c3296b34630b91eeb316",
+       "013b891d182045ff5a0ebe1edcb7ee5c5fd02720",
        []
       ],
       "transform-interpolation-animated-ref.html": [
@@ -252291,10 +252693,6 @@
       "transform-interpolation-ref.html": [
        "2fee6f7c1fc46593f450fac606a651a12403ff72",
        []
-      ],
-      "translate-interpolation-expected.txt": [
-       "0499ca03b5ee21961e69a72ab904c4110d35d9d9",
-       []
       ]
      },
      "backface-visibility-hidden-002-ref.html": [
@@ -252470,14 +252868,6 @@
       }
      },
      "parsing": {
-      "rotate-parsing-valid-expected.txt": [
-       "8aed22f088488ae88c3298d67950396453e84d87",
-       []
-      ],
-      "scale-parsing-valid-expected.txt": [
-       "393c8d1d0cfe12a589e0f17bbe4c4fa200cae684",
-       []
-      ],
       "transform-box-computed-expected.txt": [
        "913e45cc787a6998589bde3856fc190e89e7de73",
        []
@@ -252491,7 +252881,7 @@
        []
       ],
       "translate-parsing-valid-expected.txt": [
-       "29d09dbe86fe32e716afb41baf9f520c6853a91c",
+       "6ab0457f1922503e980649c4defde331a92b8b0e",
        []
       ]
      },
@@ -253677,12 +254067,6 @@
       "f72f11dccae5e8b63de6148573723f86fbb4c708",
       []
      ],
-     "animations": {
-      "text-shadow-interpolation-expected.txt": [
-       "613595bf62495063841a65b61d2f71af7596d3b3",
-       []
-      ]
-     },
      "changing-while-transition-004-expected.txt": [
       "fb9a59feae5051b296630e58f0a2bc1491ccb096",
       []
@@ -254081,10 +254465,6 @@
         "4b09d7ceed421652cc7a0746f5bd6939c6bbc3d3",
         []
        ],
-       "font-synthesis-expected.txt": [
-        "229f78d9a3d112d5acffcc42197f6538149ebb8c",
-        []
-       ],
        "font-variant-alternates-expected.txt": [
         "eb3fecfa68608dc6c2cff20237cfb4f934873dcc",
         []
@@ -254315,6 +254695,10 @@
       "548a76a3407ac8a48f9f108559957cf061f20a19",
       []
      ],
+     "nothing-below-ref.html": [
+      "c8d6508ace4e4bd0343f67f2e12e35ea6e098df9",
+      []
+     ],
      "outline-offset-table-001-notref.html": [
       "aafa2b053cb30d77997743a226901d6dd4472724",
       []
@@ -259143,24 +259527,6 @@
       "930b762b01a1a75e5b5ab4fb18dedd5939618fe1",
       []
      ],
-     "animation": {
-      "backdrop-filter-interpolation-001-expected.txt": [
-       "f54727be892172c15be80a3d9daf2f70b2f17046",
-       []
-      ],
-      "filter-interpolation-001-expected.txt": [
-       "38b35eb2f945e9e955f1b9834a4bd8f8cec8ff9d",
-       []
-      ],
-      "filter-interpolation-002-expected.txt": [
-       "cbb055689f368bdbf80d40d54696467166596a4b",
-       []
-      ],
-      "filter-interpolation-003-expected.txt": [
-       "2080b37a3d8da56bb9e42657e2a0e4c9750e5d79",
-       []
-      ]
-     },
      "backdrop-filter-basic-background-color-ref.html": [
       "4997007f0bf858986b8f0fbbe8348153cfee1dd6",
       []
@@ -259929,6 +260295,10 @@
        []
       ]
      },
+     "test_media_queries-expected.txt": [
+      "eb669b4b788e6e140431abdea07e99a7eedf1772",
+      []
+     ],
      "viewport-script-dynamic-ref.html": [
       "e3f1c95d66fcd89bdce9fc08e31e798df3053e32",
       []
@@ -262410,7 +262780,7 @@
       []
      ],
      "delete.js": [
-      "5e36c557fcf10fd52bb7592cb14e34b3a1d2523b",
+      "183451ec3d30c86a8b49dbc6a99f7f0062a8b81d",
       []
      ],
      "fontname.js": [
@@ -262430,7 +262800,7 @@
       []
      ],
      "forwarddelete.js": [
-      "ffd7dadd4df846ac7e7db61257da0a475d63c863",
+      "cc03bcd26eed87c9a94db63772002481d548b775",
       []
      ],
      "hilitecolor.js": [
@@ -262502,7 +262872,7 @@
       []
      ],
      "multitest.js": [
-      "338b9c905d66494768b05933bde0affe1d51bd35",
+      "47e5849fece76172cbabf4b446b63e74fa682b50",
       []
      ],
      "outdent.js": [
@@ -262606,11 +262976,11 @@
       []
      ],
      "insert-paragraph-in-void-element.tentative-expected.txt": [
-      "989dab85fe1920b567c2f87afdbd20494623cec3",
+      "7bcb233f3cf0975396e2296e21fb721d15e1fc95",
       []
      ],
      "insert-text-in-void-element.tentative-expected.txt": [
-      "9cbdf9306c899d491bcb49768185a0999329c34c",
+      "c287839fd756bc9abc36ac1906343e47f43c9784",
       []
      ],
      "insertlinebreak-with-white-space-style.tentative_pre-line-expected.txt": [
@@ -262700,7 +263070,7 @@
       []
      ],
      "delete_6001-7000-expected.txt": [
-      "732c8ae6294483a081e4edc9f9054174b8012b5d",
+      "473aea3778cbec1bda0ae362449fc916e84afcab",
       []
      ],
      "delete_6001-last-expected.txt": [
@@ -262947,6 +263317,10 @@
       "a03176b9880655577bf674d15994a55f98937228",
       []
      ],
+     "justifyright_4001-last-expected.txt": [
+      "4e79c28ca7083c4cbb4d0ac018cbaf77a760b652",
+      []
+     ],
      "misc-expected.txt": [
       "0d601ee3934bd605b61d3964fe81be2316b40ac1",
       []
@@ -262992,7 +263366,7 @@
       []
      ],
      "multitest_9001-last-expected.txt": [
-      "885c30d52f2831a907e2cf68472f2256cffd100a",
+      "26d9c15b06c7f169530f2d6694d77d84f4a14192",
       []
      ],
      "outdent-expected.txt": [
@@ -266588,14 +266962,6 @@
      "b007264cea5db3c1ad6f2825ae44b149445dcaec",
      []
     ],
-    "local_FileSystemBaseHandle-move-manual.https-expected.txt": [
-     "68675641c404e9b6bcd81c36597a521afe64815c",
-     []
-    ],
-    "local_FileSystemBaseHandle-rename-manual.https-expected.txt": [
-     "7f803f9040382e74e1cd063224c4b5773e7de2f2",
-     []
-    ],
     "resources": {
      "data": {
       "testfile.txt": [
@@ -266656,22 +267022,6 @@
       []
      ]
     },
-    "sandboxed_FileSystemBaseHandle-move.https.any-expected.txt": [
-     "484a904eeb41013be55176031c6b1a7a2b8f704a",
-     []
-    ],
-    "sandboxed_FileSystemBaseHandle-move.https.any.worker-expected.txt": [
-     "484a904eeb41013be55176031c6b1a7a2b8f704a",
-     []
-    ],
-    "sandboxed_FileSystemBaseHandle-rename.https.any-expected.txt": [
-     "95afc342c93248f53dde56a17dd9cb015dd1bd66",
-     []
-    ],
-    "sandboxed_FileSystemBaseHandle-rename.https.any.worker-expected.txt": [
-     "95afc342c93248f53dde56a17dd9cb015dd1bd66",
-     []
-    ],
     "script-tests": {
      "FileSystemBaseHandle-IndexedDB.js": [
       "855e52f04ddf2f4f8641524010216c6e8c7cdda7",
@@ -266681,10 +267031,6 @@
       "8c0b3521c3faed445e95f4fded160d5ac497e578",
       []
      ],
-     "FileSystemBaseHandle-move.js": [
-      "60885020ac156cf980eb552300aa8445863c6103",
-      []
-     ],
      "FileSystemBaseHandle-postMessage-BroadcastChannel.js": [
       "6c3ae7d49bc7c9a2cb49c6b214b3ec022a8790d4",
       []
@@ -266721,10 +267067,6 @@
       "8e3daba7abc07797c356172bcf7a70c0dd11ed67",
       []
      ],
-     "FileSystemBaseHandle-rename.js": [
-      "646f7c545b4911e3397d82f94a5b21f44388e1a7",
-      []
-     ],
      "FileSystemDirectoryHandle-getDirectoryHandle.js": [
       "48a4ce4ce69e8f6823db6fdd0c83a2a0c3378f32",
       []
@@ -266737,10 +267079,18 @@
       "3e721a0f017f0b393dba05a4f3b8dc098f6c0698",
       []
      ],
+     "FileSystemDirectoryHandle-move.js": [
+      "368e76ee4b05cf20c7a46527022c0d97c443aa65",
+      []
+     ],
      "FileSystemDirectoryHandle-removeEntry.js": [
       "7cdfb8fd6b519e1b6da5b1d51aa8f45ee18aac76",
       []
      ],
+     "FileSystemDirectoryHandle-rename.js": [
+      "315303b0740a190edba52bfcd514ddbcfafe9dd5",
+      []
+     ],
      "FileSystemDirectoryHandle-resolve.js": [
       "a8900f97e54523f29bdc9afcd021d32c9dbb0e08",
       []
@@ -266753,6 +267103,14 @@
       "80593418bb1622b76e440a1c55cd745c59b8a582",
       []
      ],
+     "FileSystemFileHandle-move.js": [
+      "7e62872adab896a4dd6adfb7569063894a7f2206",
+      []
+     ],
+     "FileSystemFileHandle-rename.js": [
+      "425fcaea5501d375cfd81eb1a31f96f8288e95f0",
+      []
+     ],
      "FileSystemSyncAccessHandle-flush.js": [
       "74517f6cf3861caf1b480bd38025c9930555d84b",
       []
@@ -271181,19 +271539,11 @@
          []
         ],
         "imageBitmapRendering-transferFromImageBitmap-expected.html": [
-         "846a45b5d2b03ee9b3fea1a20e6cfe13bec9cfff",
+         "747615f5fbff0a2415e61b89e720e0d41d2c6f1b",
          []
         ],
         "imageBitmapRendering-transferFromImageBitmap-flipped-expected.html": [
-         "a0f3c5dbd902a339d18f03d1006e6e6b5fe68540",
-         []
-        ],
-        "imageBitmapRendering-transferFromImageBitmap-flipped.html": [
-         "91bd024044516b77cea37c193403c829320fe60f",
-         []
-        ],
-        "imageBitmapRendering-transferFromImageBitmap.html": [
-         "59d27e0a342c7d961754a5bc338b9963189c33a0",
+         "5e216719736f816b827c6d30e4bc223bee20df22",
          []
         ],
         "transfer-worker.js": [
@@ -272092,6 +272442,10 @@
        "serviceworker-partitioning-helper.js": [
         "288ad5954e2d51c17c1088dac428927f63321bbf",
         []
+       ],
+       "sharedworker-partitioning-helper.js": [
+        "8b416c33d72cf55f080e1a1011bdb45718c8f258",
+        []
        ]
       }
      },
@@ -272257,6 +272611,10 @@
       "8df98474b589d070992677cb0134bd47bd0509c4",
       []
      ],
+     "require-corp-cached-images.https.html.headers": [
+      "6604450991a122e3e241e40b1b9e0516c525389d",
+      []
+     ],
      "require-corp-load-from-cache-storage.https.html.headers": [
       "8df98474b589d070992677cb0134bd47bd0509c4",
       []
@@ -272290,6 +272648,10 @@
        "6604450991a122e3e241e40b1b9e0516c525389d",
        []
       ],
+      "corp-image.py": [
+       "29689c45d6ad6f6cc5f020790dfb0f5455ffaca7",
+       []
+      ],
       "cross-origin-isolated-frame.html": [
        "b79fe288b3ba6de26ccd15947e8521839a18c62a",
        []
@@ -272314,6 +272676,14 @@
        "a6b74ad924aa108e15603544f7b0a80a3e18940b",
        []
       ],
+      "load-corp-images.html": [
+       "1251b8c470763d4410349892e09325025627a184",
+       []
+      ],
+      "load-corp-images.html.headers": [
+       "8df98474b589d070992677cb0134bd47bd0509c4",
+       []
+      ],
       "navigate-none.sub.html": [
        "f2fc38ff14532c4189339353cd667d2e9045785f",
        []
@@ -279289,7 +279659,7 @@
          []
         ],
         "image-loading-lazy-below-viewport.html": [
-         "486aeb0f24f4872ebb7b384db5b44cbcf01342b7",
+         "f25bd6f4d09fb53d6753f5da1853a59998e09257",
          []
         ],
         "image-loading-lazy-in-viewport.html": [
@@ -280211,6 +280581,10 @@
           "2bee3ff9966cb5a84afba6e3f4fb843d5ad7394b",
           []
          ],
+         "record-fetch.py": [
+          "4928cb4acb9eb591a2e1ac80cf8a81982a353313",
+          []
+         ],
          "referrer-checker.py": [
           "c1eaed8e468b6e50a8a49d9e2a0cdccf4479c65d",
           []
@@ -280223,12 +280597,12 @@
           "9beac4d618040083435e2a4077cc8c668f1bc00b",
           []
          ],
-         "worker-dynamic-import.js": [
-          "6f6852ce5501cf05255f9b341cdd3dc12f8792a7",
+         "worker-dynamic-import.sub.js": [
+          "791bd7d3f949940e91eee181095d61db725c7eb7",
           []
          ],
-         "worker.js": [
-          "c97d9652d3583f555f64fd2eccda3ba677f2fca1",
+         "worker.sub.js": [
+          "ffee312d21e094e9c3ff2627bd74c77b9700717e",
           []
          ]
         }
@@ -281986,10 +282360,34 @@
          "d2926eeb95e1c2e308187a8702adb3c894161c40",
          []
         ],
+        "link-rel-alternate-stylesheet.tentative.sub-expected.txt": [
+         "94ed72ac26bec78b9fb9a1584ed608b38386a059",
+         []
+        ],
+        "link-rel-stylesheet-disabled.tentative.sub-expected.txt": [
+         "968eb6788e3f3c7bf15c52c75a9246af9a097a4c",
+         []
+        ],
+        "link-rel-stylesheet-nomatch-media.tentative.sub-expected.txt": [
+         "c8638eaacb10a3ab546dfdc0868a79f26aa1a3a3",
+         []
+        ],
+        "math-font-script-src.tentative.sub-expected.txt": [
+         "7aa48ff91f98581fdb5f46b5e6ecae2788cdee5c",
+         []
+        ],
+        "math-script-src.tentative.sub-expected.txt": [
+         "ec629926535450571f5412cdfe99067b73d4fe0e",
+         []
+        ],
         "meta-csp-img-src-asterisk.tentative.sub-expected.txt": [
          "3ecb938cf5718f5744accbd18e6ce3ff4d5fa67a",
          []
         ],
+        "meta-viewport-link-stylesheet-media.tentative.sub-expected.txt": [
+         "576fb8b54260580b3634d8167d21a3c84187d2b0",
+         []
+        ],
         "picture-source-br-img.tentative.sub-expected.txt": [
          "bb7b7ce16991ac90fc7d423a480d16370864aa7e",
          []
@@ -282006,6 +282404,10 @@
          "cbedbdc6347d4b19f1e760758304a8497ca9fb67",
          []
         ],
+        "svg-script-src.tentative.sub-expected.txt": [
+         "723d0f0207a7c8439bf58dc0a781d715490397e5",
+         []
+        ],
         "svg-script-xlinkhref.tentative.sub-expected.txt": [
          "875ac8fd04f39dab079abeef0564c3d8be315658",
          []
@@ -282016,6 +282418,26 @@
          "23bf3f583cc5d44c2f2cc2f9b0482d5aa11bb1be",
          []
         ],
+        "link-rel-alternate-stylesheet.tentative-expected.txt": [
+         "b426a44b54a5714cd5e3e5c0c6f115c4acf83f66",
+         []
+        ],
+        "link-rel-stylesheet-disabled.tentative-expected.txt": [
+         "a7c3af2a87bdb646a6c91fb95d119a80539fbc70",
+         []
+        ],
+        "link-rel-stylesheet-nomatch-media.tentative-expected.txt": [
+         "67d3862ec70f54f112a37e660ada58f58acf8dba",
+         []
+        ],
+        "math-font-script-src.tentative-expected.txt": [
+         "2e7bc0c57965c2a359d2b67c88e6d158c204dd4d",
+         []
+        ],
+        "math-script-src.tentative-expected.txt": [
+         "33b59f453480f2ede6bec719d339e4aac2c7a899",
+         []
+        ],
         "meta-charset-script-src.tentative-expected.txt": [
          "94d46f00c2db5bc2582895e6658df3b4a82123d3",
          []
@@ -282024,6 +282446,10 @@
          "4309a699b5d9f5a23a51cf656569215c577177d1",
          []
         ],
+        "meta-viewport-link-stylesheet-media.tentative-expected.txt": [
+         "0f07131d0904495d6ec8c5009f21f2f684fa9bc1",
+         []
+        ],
         "picture-source-br-img.tentative-expected.txt": [
          "814d2b66fd3776e359f537bb2209bb93362269ad",
          []
@@ -282254,6 +282680,10 @@
          "a1bd0cf4466e0168e9a6f42f3646f3f321033bbc",
          []
         ],
+        "svg-script-src.tentative-expected.txt": [
+         "eb1783c9343899a04d7152c6ab9b3afcb9336866",
+         []
+        ],
         "svg-script-xlinkhref.tentative-expected.txt": [
          "402efee4a46f097b26626cee441e716668196512",
          []
@@ -282476,7 +282906,7 @@
         []
        ],
        "stash.py": [
-        "2f33da9ffffd62cc1f4596d3df6f24de16097fe6",
+        "91e3e480d254c561b6b307ab486a4522f875bab5",
         []
        ]
       },
@@ -292730,6 +293160,12 @@
      "58435be6312cb06f936117c631679663c4ed2b07",
      []
     ],
+    "css": {
+     "scroll-timeline-cssom.tentative-expected.txt": [
+      "116f38ce142edb0efb004461c1a8a9a314c36283",
+      []
+     ]
+    },
     "idlharness.window-expected.txt": [
      "130fdb6c1b681ccf9b172eebc705737ab8bbea13",
      []
@@ -293002,6 +293438,10 @@
      "64938c92982f45c7ef5ad5e6262e1401087c4423",
      []
     ],
+    "README.md": [
+     "7040cf0a9d000d25367033a9ec5a5ebbb4690398",
+     []
+    ],
     "resources": {
      "automation.js": [
       "e88fdb1a9d23dfd601d5e9e6e11b560be07d577e",
@@ -299265,12 +299705,6 @@
        []
       ]
      },
-     "combining-effects": {
-      "applying-interpolated-transform-expected.txt": [
-       "b93bdd6ea53448aa7c6cce7dab7f1d610bd112c9",
-       []
-      ]
-     },
      "keyframe-effects": {
       "computed-keyframes-shorthands-expected.txt": [
        "03400ec387856e7c7a2a1d30508bc5e52a08bf20",
@@ -299281,7 +299715,7 @@
        []
       ],
       "effect-value-iteration-composite-operation-expected.txt": [
-       "c58ee7c7725923f34f41db57057d18c1624959c6",
+       "4be9f3481dbc7d5f9ea989b1e8f5970e7f6a375b",
        []
       ]
      }
@@ -299580,7 +300014,7 @@
       ]
      },
      "test-helpers.js": [
-      "32215bbcdd05d88f372cf0520052876828c6ec03",
+      "90900e02586301f975704bcc2a414d2e6fc7f03c",
       []
      ],
      "urn-uuid.har": [
@@ -299734,17 +300168,73 @@
       []
      ],
      "resources": {
+      "accept-header-test.js": [
+       "0c50c40ad1521d59c72a1f85cfcad5261170485e",
+       []
+      ],
       "check-cookie-and-return-bundle.py": [
        "0d4f14ecb7921edfcb4583b0611d5787a36a1015",
        []
       ],
+      "element-removal-test.js": [
+       "057ab1646cfd6a585f237da8a291bd03816b1f1b",
+       []
+      ],
+      "nested-bundle-test.js": [
+       "aafde46978716836d8ace828b900e7661cebaffe",
+       []
+      ],
+      "network-error-test.sub.js": [
+       "226630de0bd4a82f3d4f5f5e20b8f98b9e526f6c",
+       []
+      ],
+      "not-found-test.js": [
+       "90307dadd9c4894b4a902f5cc0efd4f666c7f278",
+       []
+      ],
+      "path-restriction-test.js": [
+       "d55aca3fdfba4d15c86ab3459578f33c848debed",
+       []
+      ],
+      "relative-url-test.js": [
+       "fa78a4a16204573f3be2a58205902b59c8c2486b",
+       []
+      ],
+      "relative-url-with-base-test.js": [
+       "1f658ac646d7f53893b9b2bcabb5210afac02aa8",
+       []
+      ],
+      "request-destination-test.sub.js": [
+       "253fda57e8233fda937b0fb3e4226edf6f5ac3e6",
+       []
+      ],
+      "resource-timing-attributes-consistent-test.sub.js": [
+       "36baee9c882b92d302184c23fe3b5ac373190e48",
+       []
+      ],
+      "resource-timing-test.js": [
+       "cb275b0864643b42982b607a8528930e9be5a101",
+       []
+      ],
       "service-worker-controlled-iframe.html": [
        "c8b7661f42212985888d1dfdf1d8729f89c4fc35",
        []
       ],
+      "service-worker-controlled-test.js": [
+       "246705927f7e26b3c92e3d4803d3bf2128c966c0",
+       []
+      ],
       "service-worker-for-request-monitor.js": [
        "f67ac706866e6dcbcce770d3bdd637e4e0af59ce",
        []
+      ],
+      "static-element-with-test.js": [
+       "c950593bab1df6d57d9231d368e85b4e41207847",
+       []
+      ],
+      "subframe-from-web-bundle-test.js": [
+       "5ed4f4bad44baff2bd46cb4a907167aa531409c7",
+       []
       ]
      }
     }
@@ -299832,7 +300322,11 @@
      "4ddf8ebc03d3d1b364a9b0752ff4046334ae4959",
      []
     ],
-    "disabled-by-feature-policy.https.sub.html.headers": [
+    "disabled-by-permissions-policy.https.sub-expected.txt": [
+     "0bed6c9378cea6535eb2b0ffcfa09acbd0f5d530",
+     []
+    ],
+    "disabled-by-permissions-policy.https.sub.html.headers": [
      "f84ca89164e17920a58d8b7dac5ec8e04c50c215",
      []
     ],
@@ -301319,7 +301813,7 @@
      []
     ],
     "RTCPeerConnection-perfect-negotiation-helper.js": [
-     "28c476ec409e1b5f53eae41aff934868abeb692d",
+     "ed647bbe78fed07eb31fb89274edee8be96ae8e8",
      []
     ],
     "RTCPeerConnection-plan-b-is-not-supported-expected.txt": [
@@ -301327,7 +301821,7 @@
      []
     ],
     "RTCPeerConnection-restartIce.https-expected.txt": [
-     "9d4d4969bc5c110c07a8a99e28c2f7b8f15242e8",
+     "7f2351afac9482f1cc4ff6d9da58b2197466b116",
      []
     ],
     "RTCPeerConnection-setLocalDescription-answer-expected.txt": [
@@ -301347,7 +301841,7 @@
      []
     ],
     "RTCPeerConnection-setRemoteDescription-expected.txt": [
-     "12a8febb5e70fd3623d1c9072ee9e536d6166e2b",
+     "a83779eae57ab90789993146191fe87cbfebfc7b",
      []
     ],
     "RTCPeerConnection-setRemoteDescription-offer-expected.txt": [
@@ -301446,6 +301940,10 @@
       []
      ]
     },
+    "no-media-call-expected.txt": [
+     "2de564ff67a7cef19df9a7bba3fce93233ca3316",
+     []
+    ],
     "protocol": {
      "README.txt": [
       "5e17fbf9c354edabaf48f6ee1d017f23d18e2171",
@@ -301756,6 +302254,10 @@
      "326368358efeaed3fb51ac2d8595b56b93743aef",
      []
     ],
+    "Create-protocols-repeated-case-insensitive.any_wss-expected.txt": [
+     "326368358efeaed3fb51ac2d8595b56b93743aef",
+     []
+    ],
     "Create-url-with-space.any-expected.txt": [
      "114fa7d07a2ffcefe166bf8e30e81b9bfa2e7225",
      []
@@ -301800,6 +302302,14 @@
      "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
      []
     ],
+    "basic-auth.any.sharedworker_wpt_flags=h2-expected.txt": [
+     "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
+     []
+    ],
+    "basic-auth.any.worker_wpt_flags=h2-expected.txt": [
+     "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
+     []
+    ],
     "basic-auth.any_wpt_flags=h2-expected.txt": [
      "97ce540c19fb64c36397c257b4a2a42fac1b8eeb",
      []
@@ -302174,6 +302684,10 @@
        "f6919e924d47316fe1b4159c89723babcdcb5b3e",
        []
       ],
+      "backpressure-send.any.worker_wpt_flags=h2-expected.txt": [
+       "f453bf19e7850b844e8afaa0ca2aebae8602d779",
+       []
+      ],
       "constructor.any.serviceworker_wpt_flags=h2-expected.txt": [
        "ea8cfb4d6b6fb2a9070f67f571dfce682f0b4661",
        []
@@ -302427,7 +302941,7 @@
      []
     ],
     "README.md": [
-     "107a5bb1447b01c213a17d304fd17792542b9845",
+     "c19e8fa3475860e2bfb57921a56b5be2b8d5fdc0",
      []
     ],
     "idlharness.https.any-expected.txt": [
@@ -326443,7 +326957,7 @@
    },
    "compat": {
     "css-style-declaration-alias-enumeration.html": [
-     "cdd9cc8eaefb94218118d9e6a74727bf5c716c17",
+     "75776e19c3b92fec92cae31d74850dcd6f67ee05",
      [
       null,
       {}
@@ -337427,7 +337941,7 @@
        ]
       ],
       "box-shadow-composition.html": [
-       "3f01473a29f52c0d505ee2253b8400431edf9707",
+       "7cc1ba299231a29276dba6bdf041e3ce9e654b09",
        [
         null,
         {}
@@ -338577,6 +339091,13 @@
        {}
       ]
      ],
+     "layer-vs-inline-style.html": [
+      "9ddfbc39075413fd421f4e8df3e65a2dd3b45f55",
+      [
+       null,
+       {}
+      ]
+     ],
      "parsing": {
       "all-invalid.html": [
        "4a1d045ecc84806fb3cf2f14a344d27c40e5bfd8",
@@ -338600,6 +339121,13 @@
        ]
       ]
      },
+     "presentational-hints-cascade.html": [
+      "729dc71666a903f9368f8cc24f4ad6836af24fdc",
+      [
+       null,
+       {}
+      ]
+     ],
      "revert-val-003.html": [
       "b819eb0b2d2b5e51242b1b71b750d73dde550c96",
       [
@@ -341964,6 +342492,20 @@
         {}
        ]
       ],
+      "font-palette-values-invalid.html": [
+       "870542ed88c4c9307c0c5219c3c4de868fecfae3",
+       [
+        null,
+        {}
+       ]
+      ],
+      "font-palette-values-valid.html": [
+       "c6774efbb14931ebf50808c3cb35fbff8a1379b8",
+       [
+        null,
+        {}
+       ]
+      ],
       "font-size-adjust-computed.html": [
        "a4c8212b980a4461ab05a26a9401c6c4e62a5143",
        [
@@ -347252,6 +347794,13 @@
        {}
       ]
      ],
+     "multicol-fill-balance-015.html": [
+      "80d452678c99569540918137a23fb8a96e67dcc8",
+      [
+       null,
+       {}
+      ]
+     ],
      "multicol-gap-animation-001.html": [
       "6a3a8d33780fe048528e1e3cd6a26707f2df4b70",
       [
@@ -348992,6 +349541,27 @@
      ]
     },
     "css-ruby": {
+     "br-clear-all-000.html": [
+      "91c5a0b63b3f54edfeb10606713f7a3d3c8fb0fd",
+      [
+       null,
+       {}
+      ]
+     ],
+     "br-clear-all-001.html": [
+      "7c71eab4dd2a812383b1eeefb335d302bd259395",
+      [
+       null,
+       {}
+      ]
+     ],
+     "br-clear-all-002.html": [
+      "487fd33b5c8841004288535694b1992a064f5a2a",
+      [
+       null,
+       {}
+      ]
+     ],
      "inheritance.html": [
       "0128ea1ee8fe3e28a1a8e409eeb87b41b857f20f",
       [
@@ -353596,147 +354166,147 @@
       ],
       "ja": {
        "css-text-line-break-ja-cj-loose.html": [
-        "def6adf0da7d6e35a7a88d086d3df19cfaca7b3e",
+        "164ac2731588639e6846db931b3354850931f038",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-cj-normal.html": [
-        "bc204f5377d9a8477e81d7215148612f4805ddc8",
+        "b6fc49e12d3f0a3f84f2a95b5fc817c24e272ad6",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-cj-strict.html": [
-        "cdb8398248238c6266c883db8aeaaa243013694a",
+        "ebf511b354443dca1771acdf42e8a32bbeba1a93",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-cpm-loose.html": [
-        "c932cb4fa3f5b01284f4e4ae2b0fc0637d0b12a5",
+        "895738712141e8ee79e1be7fb7390fcec8d0f44c",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-cpm-normal.html": [
-        "7816fb53b0bca5cf52672802fb005be89c9f3b8b",
+        "ccb5f951c2b7588360bde8cad99add0bf438bf99",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-cpm-strict.html": [
-        "833e45e6b58ac2aee90967a706a3ae82d122a224",
+        "7f9fdb8c47aaefc3beb37c61566168198c6450d8",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-hyphens-loose.html": [
-        "a8a6836bd54a3ef808cdd20fe9b77629e33a2fc4",
+        "771635bf676965df90318dab3d57f343f696d0bd",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-hyphens-normal.html": [
-        "364eddaadb7e765c93fe248b36729f22c502114d",
+        "eba18437e6fdd589b7b9db326eca0231064ebc70",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-hyphens-strict.html": [
-        "87cc6f602a47c8e3eb77965ae15c0d83334f3804",
+        "c7e2d2aaffb8c735b0bbaa1d1eceebda39b3a921",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-in-loose.html": [
-        "235d38177cbb91cf6f6f3f4d512593516409f770",
+        "c45691a976172239b0a30c714645a8c2f82cdc76",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-in-normal.html": [
-        "7bdedd5a82f8ce37cb2ea57f24efd9058eebf8ef",
+        "a92d53aa605948a7bda1c67b5336cb76a2ee70f1",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-in-strict.html": [
-        "58c05bb0868a0154c8caabb9bb744786c59a527e",
+        "ccbf08e5bca9a2a9332c7d71004fb06e053af51b",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-iteration-loose.html": [
-        "49f51f4b7d29107a20b31d81131459cf86d84d9d",
+        "9d9e241e01edbec91ddf15d98f23abdfb581a88b",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-iteration-normal.html": [
-        "55f54ea84b193a9595287baa12231c7fa3ae754d",
+        "1b88d220d7c2f4b1717462414a24fb4955f59920",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-iteration-strict.html": [
-        "1c2cd9a5d430fbc3df261b107c47614477f52fae",
+        "f14d140d9c07df733fa6f5da8aeec1b8b3b12630",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-po-loose.html": [
-        "4d79a1227801f47b317d5b18e117b38a8bc65d86",
+        "111c799a3c625cd964d3bdf76685034c05571284",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-po-normal.html": [
-        "eb3003c27212b637df0b5f390447d5c3ee62928b",
+        "21c27195aecb5d0905e3f8282d247c360a03d350",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-po-strict.html": [
-        "08e16f26321bab7ca03f2cfe6eddd0c324d765dc",
+        "bed89ef338118d4c92c61aa5a0c9ba7fef99b9b0",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-pr-loose.html": [
-        "fde2a3d086b16ee1817e5928015d19c5016340c6",
+        "cb600dfcd81f0ac4154670bcb304ba2d9fb1db86",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-pr-normal.html": [
-        "d6f58cb88c1d0b81351eedb3830568fa7a7713b2",
+        "130889de6a279ce75a823ad934c98e00c45db975",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-ja-pr-strict.html": [
-        "8265f917225e247538c9fa2f3b28cf7e0382b2ed",
+        "6b83bda113107af002bd5b040ec21c6c607fcb8d",
         [
          null,
          {}
@@ -353745,147 +354315,147 @@
       },
       "other-lang": {
        "css-text-line-break-de-cj-loose.html": [
-        "c902bf7bddb23db69a23ad70cc4ef5f3c85e4aa0",
+        "0a76b9338c74d3d99b0ce013b16f8208a9c84965",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-cj-normal.html": [
-        "e98d4a20cb1f80111b22fc7cb30d079ac3f12009",
+        "a5339b4a2b2453bea8da05d44344ecfc9159e991",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-cj-strict.html": [
-        "29810f2a3502c9b24364c626af22d591c0f0406a",
+        "ebfbed7025c39251d0f41f120e135ec9f5ca5a18",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-cpm-loose.html": [
-        "9dffd854891a195c8d590ade08ea29e0ff2a585a",
+        "7937664b90f5a2bbe6af4d3a4cd3e8cff677a3bc",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-cpm-normal.html": [
-        "9c0af13806ca8b612700856f8007152449e3a5a8",
+        "0818c4364d5db68cb2d10c338861a4d91c7c03f1",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-cpm-strict.html": [
-        "d573bac7d6b69b2fbf702aabfc656a151b15171a",
+        "97d2cc6d645f2edf0f6870b02acb1aaf0f831ea8",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-hyphens-loose.html": [
-        "0455915d7da436a8b77ba9fd305c09a05c266c62",
+        "611c0617e90db03f3be4afce986b666ad9ff43e7",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-hyphens-normal.html": [
-        "fc23481036fc7debcdee7af7266b408afd066c01",
+        "f8ca72337e6dd92da27e65e64de6f7f69a44f001",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-hyphens-strict.html": [
-        "bec4937eb135690766353472803cb7b7947ab367",
+        "4cab0c4914318fb66f1f89422b287648d81a5322",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-in-loose.html": [
-        "fff23f36df8f22161c841ae93b637426315c9552",
+        "e1ea5c5414e1cd55fe497a4cffe7f8820394694b",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-in-normal.html": [
-        "d000d8eb16d55e53eab708eabec21d6d95a22fe7",
+        "42307521ff95dc963cc99a522e2d25280ff9cff2",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-in-strict.html": [
-        "79d6e12cc8eb3d2dfcd0544f2a4cc89a80f4223b",
+        "9e9ff0c1b69de9337d827613da85eaf561bddc5d",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-iteration-loose.html": [
-        "ff8ef05b14c8abac40ea2ac6c8c667a7062b97fe",
+        "065820f2c3b8c1769cdd87c518841a26c1f1a216",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-iteration-normal.html": [
-        "c5913821e5bd37d706f98818524df6c74b7519b0",
+        "3124d5cd965c8899b1b7ce1e06ca23e587bc66c8",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-iteration-strict.html": [
-        "46c0fe3caacc6a7dec51fe75d9186385937ec901",
+        "774da5dcfe45fdc546f0f8cd531599875195c9ee",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-po-loose.html": [
-        "0eec96857fd6bb8f2b812dc91c42cebf422ec2f7",
+        "e133b0679e0d684b0bdf9b549ee9fdbece63c2ec",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-po-normal.html": [
-        "6043912cded98d4a37087f2bca85f7dfa4c8c7f4",
+        "8e3efaa364deaffa3a336fa9c72ec8eed5d304cd",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-po-strict.html": [
-        "8c9387fa044ae0cb5c95be33737395cf020a4cde",
+        "00cc1e41a25e08413802d977398afab9bd1eeb12",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-pr-loose.html": [
-        "ba3581a7bcbea362d7115a729dc7a796d215bdf1",
+        "59583659418847b52affcab9d54896f108701116",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-pr-normal.html": [
-        "477a7796530f77c2d01229873d3e3066528aed92",
+        "28cbaf25fca18f6bbbbbb99b69302b4ff0f241f9",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-de-pr-strict.html": [
-        "4d4bee52a866ad6c010de9f0f0be589cb9aa0c80",
+        "4a96c8f178a10af761ae1563c8b320de8be11378",
         [
          null,
          {}
@@ -353894,147 +354464,147 @@
       },
       "unknown-lang": {
        "css-text-line-break-cj-loose.html": [
-        "d6d0a1b3493af9a5f06b296cc0545e29cf1bf29f",
+        "dd53abb141c55e42b4e5475e657c64a2c41f28a8",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-cj-normal.html": [
-        "548fa17398287e4e3c8c210f1bb0e72a43d87af1",
+        "faf8d401fba0d1844a308df1d1fe9bca3e818210",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-cj-strict.html": [
-        "a4e871789a30ff001b6bf278a87edb54b4ebe733",
+        "855d271af9619b879f50de0ace1461f75559ff97",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-cpm-loose.html": [
-        "3d4cb261289599df2141a534620654cd995eccaf",
+        "783582512fb2b1a5230ec6091ff363d10f97ee93",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-cpm-normal.html": [
-        "417973b0bbf1ce2730765d5ad5087b2f894c4db9",
+        "128d6008de7a70dfa217b9c8d6a921cf06462d12",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-cpm-strict.html": [
-        "c6685dfe79d875034b8bdc4d4a8de70a09e33948",
+        "d13307d2a9924a44eb68d928785a4731f4982046",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-hyphens-loose.html": [
-        "ab9624fd4d00e2255676bda6c764f9fadd98f833",
+        "2cd6e720fabf6a3ccbc4d26d6fe272e9f3963638",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-hyphens-normal.html": [
-        "a20e2447826d62ed32d597508326d5743c0db357",
+        "c506a0d6fa9766d4939969dcd4c1196c34c2f51a",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-hyphens-strict.html": [
-        "3f2e04c0459ce49b602423e53665b2e6c8b132a8",
+        "22b07b82d97fb1aaeb0cc84014e2f68fc78034f6",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-in-loose.html": [
-        "c507f78e6e403b7d1f386299a34f12fcf613e3e8",
+        "f724244738bc092bd58694e3a3c641f881596a77",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-in-normal.html": [
-        "4e8d9617baf1a66ff15fb7dc8d6d4767aa62da97",
+        "e86775d0363c30a4556f27a847df25d44fb89a99",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-in-strict.html": [
-        "a1c3a855041d589ea47d90c636e69f215bc27b1c",
+        "92e6c5d2b1bf1592dfaf5ecd9b86f2a94e347e05",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-iteration-loose.html": [
-        "420a7b6f07c2a4dbd06f7361d37d1f2cb1a26a88",
+        "29d858565d31d904039d587ecd37a69e5ae42d83",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-iteration-normal.html": [
-        "9d7b2c032d54b693b3fd343a44089e27d70d3963",
+        "c5e29373f1bf56b6ce4a9416a02010b80df10c3d",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-iteration-strict.html": [
-        "54c7559d109b5591e722fe8290e2c11f1da97d08",
+        "2fe1cf0821d795ea38de8241fda91b5d297c9fe2",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-po-loose.html": [
-        "e635075a4151604e7a9b59900cde690e90c84e87",
+        "b2686666e1d89c18e5ffddd2dc27b05df69e3742",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-po-normal.html": [
-        "46e7472208e295d53bdd7c114bbd6f10dd354d2c",
+        "d50c8b30354bb48404c119a3b5982a62662eaf85",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-po-strict.html": [
-        "61fd7b7ec5ca51d0ce6eddc8392c58a6281e2e74",
+        "0f1420d1b0decfd7a89f7e020dffd5af001d0f43",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-pr-loose.html": [
-        "97be026e59915e3ad0a16461cb0de1b14d8efce0",
+        "e966da22f8fa2e8f19e1e9d0d099c450830ba288",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-pr-normal.html": [
-        "4e30c4e3258735bdcdbb7dc84b401d9b81c71112",
+        "1ae3a6e557b60408d21a343b91977e800662cc43",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-pr-strict.html": [
-        "b8d0fa5c17740de86053aa378b2f1cd31e6709d4",
+        "7dddd5f25665ef091326430f96ff52e398774fb9",
         [
          null,
          {}
@@ -354043,147 +354613,147 @@
       },
       "zh": {
        "css-text-line-break-zh-cj-loose.html": [
-        "a131395e1daff855eaf3f787fddeb60f73318dc1",
+        "2b65c2d8381d9fe562ee34c082c91df01c03fe23",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-cj-normal.html": [
-        "ff7456b82148c8c780e700185e11d8cda97bb51c",
+        "adda199da328799b9b57d8f6372d68ddb92a1949",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-cj-strict.html": [
-        "dc752f1086c1346404766372d268f6c2be3c5979",
+        "bbae688d4722cd55a157bb134992bfe79f8d45bb",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-cpm-loose.html": [
-        "4044e10666d15573fa4d7b3d455b956895eae19e",
+        "38c207db0dc5c41bcdfb8d20228e50c9e05225c9",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-cpm-normal.html": [
-        "01096b26bae5e195788d6f87f55bb267c73cd938",
+        "edeb465b1edc7e0c594f9fce0e14e9ca9a5f5caa",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-cpm-strict.html": [
-        "8460aaa0de7137999b9f2ca89435d9e71ccb6902",
+        "235bd712d037ed507557428582d2cc7b2817585b",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-hyphens-loose.html": [
-        "103d8afd00bd223737f2607bf090e40cacda0219",
+        "5d4ab12bc86c23ad8ec2236f103250481cc06945",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-hyphens-normal.html": [
-        "5481b824601e5957c2ec98a530ef55392510700f",
+        "1a07353fceaa5500e0f27d7daea2cddee2e05bea",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-hyphens-strict.html": [
-        "bf61555a312ca6bba42c23d51eb3fa721d00ca7a",
+        "8ac874e29c5399e0d3028c28c2153d0f19b787c9",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-in-loose.html": [
-        "e7686617a0a893f2280efe794095776961cce164",
+        "56fec0bd3edba1ee681a0dc6ae906120f28c6677",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-in-normal.html": [
-        "a9409cfe8d7aab5b8308fca9b56d6addf6f30a83",
+        "67d1668179d78fda58e8b14ab12d8719d04eaea6",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-in-strict.html": [
-        "defdf223074b76ef4783bb63c7bafbd226927b67",
+        "a03f8fec756b35b62b40e75d1d3a0f7987d88da7",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-iteration-loose.html": [
-        "64f821925c01fa471ac31c20f802b75a349c24a4",
+        "6ac29a1fb4d2b6d0dd3b93eed78b75b443a43bd3",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-iteration-normal.html": [
-        "a7f66ea2b6b027ec8afcffc3983e6e5f939b9d02",
+        "8f5276ac040ba7b99f1f4a1a8043b9c5e4046c9c",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-iteration-strict.html": [
-        "0b1ca2a6c16beaa6f557add655b9d12a5833bb12",
+        "678e43d767bf0fc05939ad8b9e08823e8260a90b",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-po-loose.html": [
-        "04a0f4d620f4a450db84fc4cea627191f0b840f4",
+        "3bd1b2f6b61c0fe1ba0100ed9f479e6f065ee8f5",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-po-normal.html": [
-        "5a52cf853e29e7c056e6f092252d2bbefc2e8704",
+        "76eed4b0590777f3090a335f817c5cd8d1218b21",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-po-strict.html": [
-        "d85b74a54056166cedbf04f694d681ef95fff9b4",
+        "991b9ffa6d54d62ba0e2a0979cf39bd03f6c3cdc",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-pr-loose.html": [
-        "b56cd28c84037387634ab0b91311fedf11522136",
+        "e3b13e060ce5c28a61c7eb8892158ac107e97614",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-pr-normal.html": [
-        "198bf28cd7e5d49e57912db6637048a1f506d887",
+        "954953cd41e05ef43440143a7586a7c4b1dcde82",
         [
          null,
          {}
         ]
        ],
        "css-text-line-break-zh-pr-strict.html": [
-        "c71014b42f90e1ca21b0df9f7184b94bfc282bbb",
+        "cefd42923a1ccaf8c1ef2bb6bf09062cb8ea465b",
         [
          null,
          {}
@@ -355157,7 +355727,7 @@
        ]
       ],
       "rotate-composition.html": [
-       "f9a4527342ffb44cf389cf9ab5ded0e59492b9e3",
+       "6ab07050542d112edabede888448093b6f303dac",
        [
         null,
         {}
@@ -355173,7 +355743,7 @@
        ]
       ],
       "scale-composition.html": [
-       "6fc4de61132cd2b3c887f9a932c2e820fd5cdb38",
+       "107aa0b273f83e97a906bbc59037ee29336a90e9",
        [
         null,
         {}
@@ -355296,7 +355866,7 @@
        ]
       ],
       "translate-composition.html": [
-       "3abdb4522b07094ca689acee9fc7e252f18438ec",
+       "3250d746a3815f5a1da9835ed1a53c86c4922a02",
        [
         null,
         {}
@@ -355468,7 +356038,7 @@
        ]
       ],
       "translate-parsing-valid.html": [
-       "04440d552c0668c72c7b028ad22eee892cf4ea61",
+       "132e041676d8194da01dd33c1af05381737646f7",
        [
         null,
         {}
@@ -355689,7 +356259,7 @@
      ],
      "animations": {
       "text-shadow-composition.html": [
-       "dc297ec9fac9dc23acd25e27f8707470a3d7685d",
+       "d7d29c416ac03d4f0c0fff1fdacbadb7dccec924",
        [
         null,
         {}
@@ -357595,7 +358165,7 @@
         ]
        ],
        "font-synthesis.html": [
-        "e7b06654c86bb5fe0a39db3738d7e8c88600fae0",
+        "0bcce9bd2132480fffdb51ca1086dbdca32411b5",
         [
          null,
          {}
@@ -362761,7 +363331,7 @@
       ]
      ],
      "test_media_queries.html": [
-      "7628c9d18a94b7044789a424839a6c5d0747ddb5",
+      "a57a4c5a4537da56574e2d322d7c96965e72fd04",
       [
        null,
        {}
@@ -368979,7 +369549,7 @@
       ]
      ],
      "insert-paragraph-in-void-element.tentative.html": [
-      "a9ecfdcd6630acc204704d3b3291a0d4c2bbd12b",
+      "c4f788a55093476c3ee3545a9032e5709709194e",
       [
        null,
        {
@@ -368988,7 +369558,7 @@
       ]
      ],
      "insert-text-in-void-element.tentative.html": [
-      "a67f061bc42775ceaba4e5693184523049a5d2ea",
+      "f84d3fce036981bb441e6e5b989341627a166b23",
       [
        null,
        {
@@ -394555,47 +395125,6 @@
       }
      ]
     ],
-    "sandboxed_FileSystemBaseHandle-move.https.any.js": [
-     "46ed52039bd0d5a563ba192a40d9447a02c6bbe6",
-     [
-      "file-system-access/sandboxed_FileSystemBaseHandle-move.https.any.html",
-      {
-       "script_metadata": [
-        [
-         "script",
-         "resources/test-helpers.js"
-        ],
-        [
-         "script",
-         "resources/sandboxed-fs-test-helpers.js"
-        ],
-        [
-         "script",
-         "script-tests/FileSystemBaseHandle-move.js"
-        ]
-       ]
-      }
-     ],
-     [
-      "file-system-access/sandboxed_FileSystemBaseHandle-move.https.any.worker.html",
-      {
-       "script_metadata": [
-        [
-         "script",
-         "resources/test-helpers.js"
-        ],
-        [
-         "script",
-         "resources/sandboxed-fs-test-helpers.js"
-        ],
-        [
-         "script",
-         "script-tests/FileSystemBaseHandle-move.js"
-        ]
-       ]
-      }
-     ]
-    ],
     "sandboxed_FileSystemBaseHandle-postMessage-BroadcastChannel.https.window.js": [
      "ca25b548cbbb4920bda1175c7af160b95b4de0f7",
      [
@@ -394965,47 +395494,6 @@
       }
      ]
     ],
-    "sandboxed_FileSystemBaseHandle-rename.https.any.js": [
-     "889fedcb5d938537d0b66e5fcf5ff6df9a5992cd",
-     [
-      "file-system-access/sandboxed_FileSystemBaseHandle-rename.https.any.html",
-      {
-       "script_metadata": [
-        [
-         "script",
-         "resources/test-helpers.js"
-        ],
-        [
-         "script",
-         "resources/sandboxed-fs-test-helpers.js"
-        ],
-        [
-         "script",
-         "script-tests/FileSystemBaseHandle-rename.js"
-        ]
-       ]
-      }
-     ],
-     [
-      "file-system-access/sandboxed_FileSystemBaseHandle-rename.https.any.worker.html",
-      {
-       "script_metadata": [
-        [
-         "script",
-         "resources/test-helpers.js"
-        ],
-        [
-         "script",
-         "resources/sandboxed-fs-test-helpers.js"
-        ],
-        [
-         "script",
-         "script-tests/FileSystemBaseHandle-rename.js"
-        ]
-       ]
-      }
-     ]
-    ],
     "sandboxed_FileSystemDirectoryHandle-getDirectoryHandle.https.any.js": [
      "69ca2bf3677f25e2fac3dcc130894d783bc62231",
      [
@@ -395129,6 +395617,47 @@
       }
      ]
     ],
+    "sandboxed_FileSystemDirectoryHandle-move.https.any.js": [
+     "70a41a56740ddd0f84a174cc6925a38f4a82587d",
+     [
+      "file-system-access/sandboxed_FileSystemDirectoryHandle-move.https.any.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemDirectoryHandle-move.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "file-system-access/sandboxed_FileSystemDirectoryHandle-move.https.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemDirectoryHandle-move.js"
+        ]
+       ]
+      }
+     ]
+    ],
     "sandboxed_FileSystemDirectoryHandle-removeEntry.https.any.js": [
      "a4be8bd267e743ee617c29c1cce1188e6b9d377a",
      [
@@ -395170,6 +395699,47 @@
       }
      ]
     ],
+    "sandboxed_FileSystemDirectoryHandle-rename.https.any.js": [
+     "d6aa0d9f8479bf0ccff852ff0b7797709d9dc934",
+     [
+      "file-system-access/sandboxed_FileSystemDirectoryHandle-rename.https.any.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemDirectoryHandle-rename.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "file-system-access/sandboxed_FileSystemDirectoryHandle-rename.https.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemDirectoryHandle-rename.js"
+        ]
+       ]
+      }
+     ]
+    ],
     "sandboxed_FileSystemDirectoryHandle-resolve.https.any.js": [
      "6ee32709307cb930c8d56374841792fd70235915",
      [
@@ -395278,6 +395848,88 @@
       }
      ]
     ],
+    "sandboxed_FileSystemFileHandle-move.https.any.js": [
+     "1f9678a041531ea8a8aed2208a2847816f54f5b4",
+     [
+      "file-system-access/sandboxed_FileSystemFileHandle-move.https.any.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemFileHandle-move.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "file-system-access/sandboxed_FileSystemFileHandle-move.https.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemFileHandle-move.js"
+        ]
+       ]
+      }
+     ]
+    ],
+    "sandboxed_FileSystemFileHandle-rename.https.any.js": [
+     "37039b83a5a55c9226b769597efa16eb1bacddcc",
+     [
+      "file-system-access/sandboxed_FileSystemFileHandle-rename.https.any.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemFileHandle-rename.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "file-system-access/sandboxed_FileSystemFileHandle-rename.https.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/test-helpers.js"
+        ],
+        [
+         "script",
+         "resources/sandboxed-fs-test-helpers.js"
+        ],
+        [
+         "script",
+         "script-tests/FileSystemFileHandle-rename.js"
+        ]
+       ]
+      }
+     ]
+    ],
     "sandboxed_FileSystemFileHandle-sync-access-handle-writable-lock.https.tentative.worker.js": [
      "a2ed99db1d538ada4d76796ccd6a6c6cfba2565e",
      [
@@ -404024,22 +404676,6 @@
          ]
         ]
        },
-       "hit-regions": {
-        "addHitRegions-NotSupportedError-01.html": [
-         "5e4502fd8dbe73bffa25a3e8116ec40ef57605c5",
-         [
-          null,
-          {}
-         ]
-        ],
-        "hitregions-members-exist.html": [
-         "b9203f56067585a6b6183df35311211c86421641",
-         [
-          null,
-          {}
-         ]
-        ]
-       },
        "image-smoothing": {
         "imagesmoothing.html": [
          "1a86a8f2015aba3f68ebec7cd4227127e744f133",
@@ -419849,6 +420485,13 @@
         null,
         {}
        ]
+      ],
+      "sharedworker-partitioning.tentative.https.html": [
+       "3b7fa5943a16a3a986fb1dfff20b9faef76e29d4",
+       [
+        null,
+        {}
+       ]
       ]
      },
      "blob.https.html": [
@@ -420029,7 +420672,7 @@
        ]
       ],
       "redirect.tentative.html": [
-       "219de4a9668695ab596ac0628e74aa398c65478b",
+       "f3bf02da6e27b2ee208f04e2d4cc179403240e4b",
        [
         null,
         {
@@ -420279,6 +420922,13 @@
        {}
       ]
      ],
+     "require-corp-cached-images.https.html": [
+      "f5eaddbdd15a8a4fae4d17195eb6d40fc1b7eacd",
+      [
+       null,
+       {}
+      ]
+     ],
      "require-corp-load-from-cache-storage.https.html": [
       "489230a776d0d5b81f30789a4263837a6798f964",
       [
@@ -427806,13 +428456,20 @@
          {}
         ]
        ],
-       "embed-document-under-content-visibility.html": [
+       "embed-document-under-content-visibility-focus.html": [
         "26a77918e0c6653cd168cd09bc1945d2851a8562",
         [
          null,
          {}
         ]
        ],
+       "embed-document-under-content-visibility-gbcr.html": [
+        "074e63bf2bd3d9e24d9fe130738d7e6c903ca5fb",
+        [
+         null,
+         {}
+        ]
+       ],
        "embed-document.html": [
         "3d44678cf161a2b9b252d31f2a66db37979d89de",
         [
@@ -428725,7 +429382,7 @@
         ]
        ],
        "image-loading-lazy-below-viewport-dynamic.html": [
-        "7fc2c74214739206cfec69b1617d59a2f36b3b3d",
+        "78f18f0c23388a780df85fa69640795d99c06270",
         [
          null,
          {}
@@ -428760,7 +429417,7 @@
         ]
        ],
        "image-loading-lazy-in-viewport-dynamic.html": [
-        "982f09b8298bccee48b24c1774ef46a5d702dd22",
+        "39dd5dc1e9a8e955331e7c1963035433581dfdf2",
         [
          null,
          {}
@@ -428795,7 +429452,7 @@
         ]
        ],
        "image-loading-lazy-negative-margin.html": [
-        "43a2c46023454106a60bd72691ec333499f69834",
+        "1651d8dda7d49d4302eaf17f3a250ed30ddf823a",
         [
          null,
          {}
@@ -428809,7 +429466,7 @@
         ]
        ],
        "image-loading-lazy-relevant-mutations.html": [
-        "cd4b99dd458c4bb0d4ddceef57b879f5e4ea697d",
+        "3a2662451e03b510bde18cfeb806d811c2df3a35",
         [
          null,
          {}
@@ -428823,7 +429480,7 @@
         ]
        ],
        "image-loading-lazy-to-eager.html": [
-        "f74cafb106947b491d45b8640e174c5cbee90bb1",
+        "62460639818800dc0e10f205e5134f96891e7352",
         [
          null,
          {}
@@ -431930,7 +432587,7 @@
          ]
         ],
         "css-module-worker-test.html": [
-         "1618f40eb6119c6b9c20047d0463daa2ef27d0f0",
+         "7ff672da6a9274ba7fb6d08c70b81406eeb795d6",
          [
           null,
           {}
@@ -459750,6 +460407,20 @@
         {}
        ]
       ],
+      "internal-import-stylesheet-with-differentorigin-base-url-from-preload.tentative.html": [
+       "4d2228c9a31873c2714a4f069c2df95a0e39db37",
+       [
+        null,
+        {}
+       ]
+      ],
+      "internal-import-stylesheet-with-differentorigin-base-url.tentative.html": [
+       "7130e2a14aeeb794da189648f2458dca3edb2918",
+       [
+        null,
+        {}
+       ]
+      ],
       "internal-import-stylesheet.html": [
        "32adf5adcad47982daef04ec1eb47d53ebf32629",
        [
@@ -468947,7 +469618,7 @@
      ]
     ],
     "observe.html": [
-     "8596d3a5f8568f714b890798f98806097d9bb1b3",
+     "a3bf784b62cfcdb1333fee35646b7bcd2b59ba38",
      [
       null,
       {}
@@ -471870,7 +472541,7 @@
       ]
      ],
      "scroll-timeline-cssom.tentative.html": [
-      "afca950a6a9f4b0c2e8654db6096e9cef465bc8e",
+      "8724ddd2559911fef2659266a4f1e7163609128c",
       [
        null,
        {}
@@ -471994,7 +472665,7 @@
      ]
     ],
     "scroll-animation-effect-phases.tentative.html": [
-     "339b3a8cdf6dfcafe5e4b55df0de68c9c70e1f14",
+     "ba4c692c087f438c95bff36571a6c6f7d8e85bc6",
      [
       null,
       {
@@ -476229,6 +476900,15 @@
        {}
       ]
      ],
+     "blur-on-shadow-host-delegatesFocus.html": [
+      "289b5543721360cfa723e6b61ca0cb672c68bfab",
+      [
+       null,
+       {
+        "testdriver": true
+       }
+      ]
+     ],
      "click-focus-delegatesFocus-click.html": [
       "8b5fb843a2dcca65951980456d2b16c17645bde6",
       [
@@ -494843,8 +495523,8 @@
    },
    "web-bundle": {
     "subresource-loading": {
-     "link-accept-header.https.tentative.sub.html": [
-      "e8aa5f902da22b04279c38a76ac13309406b6483",
+     "link-accept-header.https.tentative.html": [
+      "3f0942685f55ef936ef8732efa969dd861139420",
       [
        null,
        {}
@@ -494893,21 +495573,21 @@
       ]
      ],
      "link-element-removal.https.tentative.html": [
-      "48f3587e663078d262f64325a2317261f9da4c36",
+      "da83d8824d24360a22ccf69faf885e8407c506f0",
       [
        null,
        {}
       ]
      ],
      "link-nested-bundle.https.tentative.html": [
-      "593683f77d3f46d78d38b5d1877aa50bd73fcaf7",
+      "0ada67ac50d4dd2ac1165cb6c89d487dc5c3676f",
       [
        null,
        {}
       ]
      ],
-     "link-network-error.https.tentative.sub.html": [
-      "23e71409b849fd73225ea3cdff556b9a21519d31",
+     "link-network-error.https.tentative.html": [
+      "ebd8542738aaac52075baf4e156c035fef2b2bf5",
       [
        null,
        {}
@@ -494935,84 +495615,189 @@
       ]
      ],
      "link-not-found.https.tentative.html": [
-      "d54ffe095f17d6ffe6c8e4375610e527cb0acb0b",
+      "89469fa13d6768e6abcb1a8dee1e61bf4d2a4169",
       [
        null,
        {}
       ]
      ],
      "link-path-restriction.https.tentative.html": [
-      "ff1bb5cef14887c978fb2fd617038e466176101c",
+      "3a5f8cbcee9e83fd45f6a13d9014116201f5f952",
       [
        null,
        {}
       ]
      ],
      "link-relative-url-with-base.https.tentative.html": [
-      "6aec28f99410e79aa2b767de01d7e652051fc269",
+      "07ba9159e9b5008fc3f4dce6178bb55bcf0142e0",
       [
        null,
        {}
       ]
      ],
      "link-relative-url.https.tentative.html": [
-      "a5d818fe7bdfbea1f6acf301cbf9935ec47e2ca4",
+      "98a22de8dc14060c8bc41dc5a50033192c661e3d",
       [
        null,
        {}
       ]
      ],
-     "link-request-destination.https.tentative.sub.html": [
-      "b1fd4e418a6b3fc7eb0902e82c25019ce5532403",
+     "link-request-destination.https.tentative.html": [
+      "2e029d1e5ef977fa0104d5e9f288869a7e168db8",
       [
        null,
        {}
       ]
      ],
      "link-resource-timing-attributes-consistent.https.tentative.html": [
-      "a73ed7d0795d5827e09509a6bc752ffe91513693",
+      "1b72464d66960bef855bc73940dfff544843fcc8",
       [
        null,
        {}
       ]
      ],
      "link-resource-timing.https.tentative.html": [
-      "7c0856fb01553bcb2452a0c4723ed8e7e532372e",
+      "42f69a19ca36c8747af77a81cf82d6f035e5d8e7",
       [
        null,
        {}
       ]
      ],
      "link-service-worker-controlled.https.tentative.html": [
-      "d2cde87a417544a566fc19fc0ccfd65ac3701807",
+      "814601f023ff62c93c7df4fdb5566f1fae17c18d",
       [
        null,
        {}
       ]
      ],
-     "link-static-element-with-base.https.tentative.html": [
-      "1b4161cea9ce8a4c0880cf05031cdf14e98e4758",
+     "link-static-element-with-base.https.tentative.sub.html": [
+      "826d2c84b25f47c6b77c0c672119019754428d0f",
       [
        null,
        {}
       ]
      ],
-     "link-static-element.https.tentative.html": [
-      "79463fff837bd3ade657105ffb04c0b939d2a195",
+     "link-static-element.https.tentative.sub.html": [
+      "558dd4495d60166c07c90a17225c9f3aa5f11aee",
       [
        null,
        {}
       ]
      ],
      "link-subframe-from-web-bundle.https.tentative.html": [
-      "84e5c5e973fdee7355edde5fce2b0a4fc6ea521b",
+      "1ffe30af1b30d123b64a327db3b9a160d0ad450c",
       [
        null,
        {}
       ]
      ],
      "link-subresource-load.https.tentative.html": [
-      "1428b62b36b9b9c8fc74f89ea896da0b9b34a25e",
+      "1faafbfc96e2603048f35734a256ea779eddb767",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-accept-header.https.tentative.html": [
+      "13082622863ee6df6d1ae5d23adb457db5d0ff95",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-element-removal.https.tentative.html": [
+      "9b837463a9e776a21b92ea53c4f45b8ed4c092d5",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-nested-bundle.https.tentative.html": [
+      "8ef63072d9dad626cad05740b98f8512f09e959a",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-network-error.https.tentative.html": [
+      "9930712016e541b611c6b2d0e1726b966a8c6823",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-not-found.https.tentative.html": [
+      "651ab866da25efd8fbcd2c62cc473271ca15a2d3",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-path-restriction.https.tentative.html": [
+      "9be710ce715710021d9f1623b455cf6e7316fdcd",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-relative-url-with-base.https.tentative.html": [
+      "5732a0935ec6a20a76a531688084ee1ba016eafe",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-relative-url.https.tentative.html": [
+      "b1a565481701832e9ecc9aad12034cd9aa810b74",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-request-destination.https.tentative.html": [
+      "a5b13accffe19cc51d1ea4c57aec8e5b1ac04aeb",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-resource-timing-attributes-consistent.https.tentative.html": [
+      "49a83311bce91dc87f05fee669cb50a86a48b769",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-resource-timing.https.tentative.html": [
+      "4bc9c1198da9f5016c6a7dde0dc6ef5dd838828f",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-service-worker-controlled.https.tentative.html": [
+      "7f2eec0bab1bff5c45aa7be003352f2d16c6f8b7",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-static-element-with-base.https.tentative.sub.html": [
+      "258e13a7693583d73ec2e113034ff0a4ff97b527",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-static-element.https.tentative.sub.html": [
+      "ba7e16bf956268796a0ace7a3561a66761826f38",
+      [
+       null,
+       {}
+      ]
+     ],
+     "script-subframe-from-web-bundle.https.tentative.html": [
+      "32768fb188884b890ff970c58b673618f5a9c272",
       [
        null,
        {}
@@ -496099,11 +496884,18 @@
     ]
    },
    "web-nfc": {
-    "NDEFMessage_constructor.https.html": [
-     "5d6b557e3ccf73d078e9dc0eda63ca31a28551b8",
+    "NDEFMessage_constructor.https.window.js": [
+     "f4d9a441b4c0c9a3ae2a0121c075471a34ecbf8d",
      [
-      null,
-      {}
+      "web-nfc/NDEFMessage_constructor.https.window.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/nfc-helpers.js"
+        ]
+       ]
+      }
      ]
     ],
     "NDEFReader_scan.https.html": [
@@ -496127,11 +496919,18 @@
       {}
      ]
     ],
-    "NDEFReadingEvent_constructor.https.html": [
-     "122070f50ed7c4fdb15947cbec68e2a62eea9a06",
+    "NDEFReadingEvent_constructor.https.window.js": [
+     "418a8a60da55ab8f556744fa2b297b90aa0907a0",
      [
-      null,
-      {}
+      "web-nfc/NDEFReadingEvent_constructor.https.window.html",
+      {
+       "script_metadata": [
+        [
+         "script",
+         "resources/nfc-helpers.js"
+        ]
+       ]
+      }
      ]
     ],
     "NDEFRecord_constructor.https.window.js": [
@@ -496186,12 +496985,21 @@
       {}
      ]
     ],
-    "nfc_permission.https.html": [
-     "af76d1b4e1f6c744ed90dc3aaecd74882ed2ea9c",
+    "nfc_permission.https.window.js": [
+     "9150a708a49859cd168debbbefb20765a8ec6d45",
      [
-      null,
+      "web-nfc/nfc_permission.https.window.html",
       {
-       "testdriver": true
+       "script_metadata": [
+        [
+         "script",
+         "/resources/testdriver.js"
+        ],
+        [
+         "script",
+         "/resources/testdriver-vendor.js"
+        ]
+       ]
       }
      ]
     ]
@@ -496239,7 +497047,7 @@
      ]
     ],
     "disabled-by-permissions-policy.https.sub.html": [
-     "93cb4443a0c5d6f7c1a14361c35ee405f3588c8f",
+     "e9ea903965032e4165beb31ef3311bc22f95f249",
      [
       null,
       {
@@ -501971,10 +502779,12 @@
      ]
     ],
     "RTCPeerConnection-addIceCandidate-connectionSetup.html": [
-     "d2cde593640451f4317cb09cba1442bb1c028222",
+     "cedc2ca8f0e6ed07c85f4fd1f06435e73d1afc96",
      [
       null,
-      {}
+      {
+       "timeout": "long"
+      }
      ]
     ],
     "RTCPeerConnection-addIceCandidate-timing.https.html": [
@@ -502087,10 +502897,12 @@
      ]
     ],
     "RTCPeerConnection-getStats.https.html": [
-     "f26a93ea28999e241e7374ff9d07f39412816aa1",
+     "8062618dd6170f81dbeb5af4a43bbcc204d96e95",
      [
       null,
-      {}
+      {
+       "timeout": "long"
+      }
      ]
     ],
     "RTCPeerConnection-getTransceivers.html": [
@@ -502142,10 +502954,12 @@
      ]
     ],
     "RTCPeerConnection-ondatachannel.html": [
-     "034365508b6bca14698537819d86c53fc1226d5e",
+     "08f206fb029573cb4b710691b6bad9547185253d",
      [
       null,
-      {}
+      {
+       "timeout": "long"
+      }
      ]
     ],
     "RTCPeerConnection-onicecandidateerror.https.html": [
@@ -502252,7 +503066,7 @@
      ]
     ],
     "RTCPeerConnection-restartIce.https.html": [
-     "0e4ecf64c853fce9d4e4a66856f2a060f2bdbb34",
+     "45a04d3a7a5314ff3cd8ff7fd21f8fc6c75f6f6f",
      [
       null,
       {}
@@ -502366,7 +503180,7 @@
      ]
     ],
     "RTCPeerConnection-setRemoteDescription.html": [
-     "3f335d71b9ab640c34b879d624fa77215488d5ce",
+     "c170f766bd3655b16c0eea1c5514e9e15aac8402",
      [
       null,
       {}
@@ -502693,7 +503507,7 @@
      ]
     },
     "no-media-call.html": [
-     "9d2598518da4bbbcb7ac78026b0737d40dcc09ed",
+     "bdd42f6fa582d855a5727d6053f73f788d5bba94",
      [
       null,
       {}
@@ -502814,10 +503628,12 @@
       ]
      ],
      "rtp-demuxing.html": [
-      "1b8dce3b45dab0d369e49498e19b2fb036635717",
+      "de08b2197f2985ac049024d1e5f44408d776f2e2",
       [
        null,
-       {}
+       {
+        "timeout": "long"
+       }
       ]
      ],
      "rtp-extension-support.html": [
diff --git a/third_party/blink/web_tests/external/wpt/content-security-policy/support/checkReport.sub.js b/third_party/blink/web_tests/external/wpt/content-security-policy/support/checkReport.sub.js
index bd447161..9cc2426 100644
--- a/third_party/blink/web_tests/external/wpt/content-security-policy/support/checkReport.sub.js
+++ b/third_party/blink/web_tests/external/wpt/content-security-policy/support/checkReport.sub.js
@@ -126,7 +126,7 @@
       reportCountReport.onload = reportCountTest.step_func(function () {
         var data = JSON.parse(reportCountReport.responseText);
 
-        assert_equals(data.report_count, reportCount, "Report count was not what was expected.");
+        assert_equals(data.report_count, +reportCount, "Report count was not what was expected.");
 
         reportCountTest.done();
       });
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-ref.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-001-ref.html
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-ref.html
rename to third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-001-ref.html
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-001.html
similarity index 94%
rename from third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change.html
rename to third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-001.html
index 5d3bc99..cf4a030 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-001.html
@@ -5,7 +5,7 @@
   <link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
   <link rel="author" title="Mozilla" href="https://www.mozilla.org/">
   <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1686961">
-  <link rel="match" href="dynamic-isize-change-ref.html">
+  <link rel="match" href="dynamic-isize-change-001-ref.html">
 
   <style>
   #container {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-002.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-002.html
new file mode 100644
index 0000000..cc859b7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-002.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Flexbox Test: Dynamic change to the inline-size of a row flex container</title>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1700580">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="This test verifies that the dynamic change to the flex container's inline-size triggers the reflow for flex items with percentage padding.">
+
+<style>
+#flexbox {
+  display: flex;
+  inline-size: 50px;
+  block-size: 100px;
+  background: red;
+}
+
+#flexbox > div {
+  box-sizing: border-box;
+
+  /* The following flex-basis and padding will give our flex item a content-box
+     inline-size of 25px, both before and after this test's dynamic change. */
+  flex-basis: 100%;
+  padding-right: calc(100% - 25px);
+  background: green;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div id="flexbox">
+  <div></div>
+</div>
+
+<script>
+/* Make sure the layout is up-to-date, which is essential to trigger the bug. */
+document.documentElement.offsetHeight;
+
+/* Change the flexbox's inline-size to trigger incremental reflow. */
+document.getElementById("flexbox").style.inlineSize = "100px";
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-003.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-003.html
new file mode 100644
index 0000000..9df13e31
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-003.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Flexbox Test: Dynamic change to the inline-size of a column flexbox container</title>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1700580">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="This test verifies that the dynamic change to the flex container's inline-size triggers the reflow for flex items with percentage padding.">
+
+<style>
+#flexbox {
+  display: flex;
+  flex-direction: column;
+  inline-size: 50px;
+  block-size: 100px;
+  background: red;
+}
+
+#flexbox > div {
+  box-sizing: border-box;
+  flex-basis: 100px;
+
+  /* The following padding will give our flex item a content-box inline-size of
+     25px, both before and after this test's dynamic change. (Note that the
+     horizontal axis is the flex container's cross axis, so the item stretches
+     its width by default to fill the available space.) */
+  padding-right: calc(100% - 25px);
+  background: green;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div id="flexbox">
+  <div></div>
+</div>
+
+<script>
+/* Make sure the layout is up-to-date, which is essential to trigger the bug. */
+document.documentElement.offsetHeight;
+
+/* Change the flexbox's inline-size to trigger incremental reflow. */
+document.getElementById("flexbox").style.inlineSize = "100px";
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-004.html b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-004.html
new file mode 100644
index 0000000..1627e32d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-flexbox/dynamic-isize-change-004.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Flexbox Test: Dynamic change to the inline-size of a row flex container</title>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1700580">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="This test verifies that the dynamic change to the flex container's inline-size triggers the reflow for flex items with percentage padding.">
+
+<style>
+#flexbox {
+  display: flex;
+  inline-size: 100px;
+  block-size: 100px;
+  font: 50px/1 Ahem;
+  color: green;
+  word-break: break-all;
+}
+
+#flexbox > div {
+  /* The following flex-basis and padding will give our flex item a border-box
+     inline-size of 100px, both before and after this test's dynamic
+     modification. */
+  flex-basis: 50%;
+  padding-right: calc(100px - 50%);
+  background: red;
+}
+</style>
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div id="flexbox">
+  <div>XXXX</div>
+</div>
+
+<script>
+/* Make sure the layout is up-to-date, which is essential to trigger the bug. */
+document.documentElement.offsetHeight;
+
+/* Change the flexbox's inline-size to trigger incremental reflow. */
+document.getElementById("flexbox").style.inlineSize = "200px";
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-invalid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-invalid-expected.txt
new file mode 100644
index 0000000..2d11c544
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-invalid-expected.txt
@@ -0,0 +1,17 @@
+This is a testharness.js-based test.
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values assert_equals: expected 13 but got 0
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 1 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 2 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 3 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 4 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 5 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 6 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 7 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 8 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 9 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 10 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 11 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 12 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 13 Cannot read properties of undefined (reading 'cssText')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-invalid.html
new file mode 100644
index 0000000..870542e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-invalid.html
@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing @font-palette-values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-values">
+<meta name="assert" content="@font-palette-values is parsed correctly.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="style">
+@font-palette-values {
+}
+
+@font-palette-values A B {
+}
+
+/* 0 */
+@font-palette-values A {
+    font-family: a, b;
+}
+
+/* 1 */
+@font-palette-values A {
+    font-family: 1;
+}
+
+/* 2 */
+@font-palette-values A {
+    font: 12px a;
+}
+
+/* 3 */
+@font-palette-values A {
+    base-palette: 1 2;
+}
+
+/* 4 */
+@font-palette-values A {
+    base-palette: ident;
+}
+
+/* 5 */
+@font-palette-values A {
+    base-palette: "a" "b";
+}
+
+/* 6 */
+@font-palette-values A {
+    base-palette: ;
+}
+
+/* 7 */
+@font-palette-values A {
+    override-color: ident #123;
+}
+
+/* 8 */
+@font-palette-values A {
+    override-color: 0 "red";
+}
+
+/* 9 */
+@font-palette-values A {
+    override-color: 0 #123, 1;
+}
+
+/* 10 */
+@font-palette-values A {
+    override-color: ;
+}
+
+/* 11 */
+@font-palette-values A {
+    override-color: 0 #123 1;
+}
+
+/* 12 */
+@font-palette-values A {
+    override-color: 0;
+}
+</style>
+</head>
+<body>
+<script>
+let rules = document.getElementById("style").sheet.cssRules;
+test(function() {
+    assert_equals(rules.length, 13);
+});
+
+test(function() {
+    let text = rules[0].cssText;
+    let rule = rules[0];
+    assert_equals(text.indexOf("font-family"), -1);
+    assert_equals(rule.fontFamily, "");
+});
+
+test(function() {
+    let text = rules[1].cssText;
+    let rule = rules[1];
+    assert_equals(text.indexOf("font-family"), -1);
+    assert_equals(rule.fontFamily, "");
+});
+
+test(function() {
+    let text = rules[2].cssText;
+    let rule = rules[2];
+    assert_equals(text.indexOf("font:"), -1);
+    assert_equals(rule.fontFamily, "");
+});
+
+test(function() {
+    let text = rules[3].cssText;
+    let rule = rules[3];
+    assert_equals(text.indexOf("base-palette"), -1);
+    assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+    let text = rules[4].cssText;
+    let rule = rules[4];
+    assert_equals(text.indexOf("base-palette"), -1);
+    assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+    let text = rules[5].cssText;
+    let rule = rules[5];
+    assert_equals(text.indexOf("base-palette"), -1);
+    assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+    let text = rules[6].cssText;
+    let rule = rules[6];
+    assert_equals(text.indexOf("base-palette"), -1);
+    assert_equals(rule.basePalette, "");
+});
+
+test(function() {
+    let text = rules[7].cssText;
+    let rule = rules[7];
+    assert_equals(text.indexOf("override-color"), -1);
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[8].cssText;
+    let rule = rules[8];
+    assert_equals(text.indexOf("override-color"), -1);
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[9].cssText;
+    let rule = rules[9];
+    assert_equals(text.indexOf("override-color"), -1);
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[10].cssText;
+    let rule = rules[10];
+    assert_equals(text.indexOf("override-color"), -1);
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[11].cssText;
+    let rule = rules[11];
+    assert_equals(text.indexOf("override-color"), -1);
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[12].cssText;
+    let rule = rules[12];
+    assert_equals(text.indexOf("override-color"), -1);
+    assert_equals(rule.size, 0);
+});
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid-expected.txt
new file mode 100644
index 0000000..d8f9ffb
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid-expected.txt
@@ -0,0 +1,23 @@
+This is a testharness.js-based test.
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 1 Cannot read properties of undefined (reading 'type')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 2 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 3 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 4 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 5 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 6 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 7 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 8 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 9 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 10 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 11 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 12 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 13 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 14 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 15 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 16 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 17 Cannot read properties of undefined (reading 'fontFamily')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 18 Cannot read properties of undefined (reading 'cssText')
+FAIL CSS Fonts Module Level 4: parsing @font-palette-values 19 Cannot read properties of undefined (reading 'fontFamily')
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid.html b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid.html
new file mode 100644
index 0000000..c6774ef
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-fonts/parsing/font-palette-values-valid.html
@@ -0,0 +1,233 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Fonts Module Level 4: parsing @font-palette-values</title>
+<link rel="help" href="https://drafts.csswg.org/css-fonts/#font-palette-values">
+<meta name="assert" content="@font-palette-values is parsed correctly.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style id="style">
+/* 0 */
+@font-palette-values A {
+}
+
+/* 1 */
+@font-palette-values B {
+    font-weight: 400;
+}
+
+/* 2 */
+@font-palette-values C {
+    font-family: foo;
+    font-family: bar;
+    base-palette: 1;
+    base-palette: "baz";
+    base-palette: 2;
+    override-color: "a" #123;
+    override-color: 3 #123;
+    override-color: "b" #123;
+}
+
+/* 3 */
+@font-palette-values D {
+    base-palette: "foo";
+    base-palette: 1;
+    base-palette: "bar";
+    override-color: 3 #123;
+    override-color: "baz" #123;
+    override-color: 4 #123;
+}
+
+/* 4 */
+@font-palette-values E {
+    override-color: 3 rgb(17, 34, 51);
+    override-color: 3 rgb(68, 85, 102);
+}
+
+/* 5 */
+@font-palette-values F {
+    font-family: "foo";
+}
+
+/* 6 */
+@font-palette-values G {
+    override-color: 3 rgb(17, 34, 51), 4 rgb(68, 85, 102);
+}
+
+/* 7 */
+@font-palette-values H {
+    override-color: 3 rgb(17, 34, 51), 3 rgb(68, 85, 102);
+}
+
+/* 8 */
+@font-palette-values I {
+    base-palette: -3;
+}
+
+/* 9 */
+@font-palette-values J {
+    override-color: -3 rgb(17, 34, 51);
+}
+</style>
+</head>
+<body>
+<script>
+let rules = document.getElementById("style").sheet.cssRules;
+test(function() {
+    let text = rules[0].cssText;
+    assert_not_equals(text.indexOf("@font-palette-values "), -1);
+    assert_not_equals(text.indexOf(" A "), -1);
+    assert_not_equals(text.indexOf("{"), -1);
+    assert_not_equals(text.indexOf("}"), -1);
+    assert_equals(text.indexOf("font-family"), -1);
+    assert_equals(text.indexOf("base-palette"), -1);
+    assert_equals(text.indexOf("override-color"), -1);
+});
+
+test(function() {
+    let rule = rules[0];
+    assert_equals(rule.type, CSSRule.FONT_PALETTE_VALUES_RULE);
+    assert_equals(rule.constructor.name, "CSSFontPaletteValuesRule");
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[1].cssText;
+    assert_equals(text.indexOf("font-weight"), -1);
+});
+
+test(function() {
+    let rule = rules[1];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[2].cssText;
+    assert_equals(text.indexOf("font-family: foo;"), -1);
+    assert_not_equals(text.indexOf("font-family: bar;"), -1);
+    assert_equals(text.indexOf("base-palette: 1;"), -1);
+    assert_equals(text.indexOf("base-palette: \"baz\""), -1);
+    assert_not_equals(text.indexOf("base-palette: 2;"), -1);
+    assert_equals(text.indexOf("override-color: \"a\""), -1);
+    assert_equals(text.indexOf("override-color: 3"), -1);
+    assert_not_equals(text.indexOf("override-color: \"b\""), -1);
+});
+
+test(function() {
+    let rule = rules[2];
+    assert_equals(rule.fontFamily, "bar");
+    assert_equals(rule.basePalette, "2");
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[3].cssText;
+    assert_equals(text.indexOf("base-palette: \"foo\";"), -1);
+    assert_equals(text.indexOf("base-palette: 1"), -1);
+    assert_not_equals(text.indexOf("base-palette: \"bar\";"), -1);
+    assert_equals(text.indexOf("override-color: 3"), -1);
+    assert_equals(text.indexOf("override-color: \"baz\""), -1);
+    assert_not_equals(text.indexOf("override-color: 4"), -1);
+});
+
+test(function() {
+    let rule = rules[3];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "bar");
+    assert_equals(rule.size, 1);
+    assert_equals(rule.get(7), undefined);
+    assert_not_equals(rule.get(4).indexOf("rgb"), -1);
+});
+
+test(function() {
+    let text = rules[4].cssText;
+    assert_equals(text.indexOf("51"), -1);
+    assert_not_equals(text.indexOf("102"), -1);
+});
+
+test(function() {
+    let rule = rules[4];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_equals(rule.get(7), undefined);
+    assert_not_equals(rule.get(3).indexOf("102"), -1);
+});
+
+test(function() {
+    let text = rules[5].cssText;
+    assert_not_equals(text.indexOf("foo"), -1);
+});
+
+test(function() {
+    let rule = rules[5];
+    assert_equals(rule.fontFamily, "foo");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[6].cssText;
+    assert_not_equals(text.indexOf("51"), -1);
+    assert_not_equals(text.indexOf("102"), -1);
+});
+
+test(function() {
+    let rule = rules[6];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 2);
+    assert_equals(rule.get(7), undefined);
+    assert_not_equals(rule.get(3).indexOf("51"), -1);
+    assert_not_equals(rule.get(4).indexOf("102"), -1);
+});
+
+test(function() {
+    let text = rules[7].cssText;
+    assert_not_equals(text.indexOf("51"), -1);
+    assert_not_equals(text.indexOf("102"), -1);
+});
+
+test(function() {
+    let rule = rules[7];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_equals(rule.get(7), undefined);
+    assert_not_equals(rule.get(3).indexOf("102"), -1);
+    assert_equals(rule.get(4), undefined);
+});
+
+test(function() {
+    let text = rules[8].cssText;
+    assert_not_equals(text.indexOf("base-palette"), -1);
+});
+
+test(function() {
+    let rule = rules[8];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "-3");
+    assert_equals(rule.size, 0);
+});
+
+test(function() {
+    let text = rules[9].cssText;
+    assert_not_equals(text.indexOf("override-color"), -1);
+});
+
+test(function() {
+    let rule = rules[9];
+    assert_equals(rule.fontFamily, "");
+    assert_equals(rule.basePalette, "");
+    assert_equals(rule.size, 1);
+    assert_equals(rule.get(7), undefined);
+    assert_equals(rule.get(-3), undefined);
+});
+</script>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-multicol/balance-extremely-tall-monolithic-content-crash.html b/third_party/blink/web_tests/external/wpt/css/css-multicol/balance-extremely-tall-monolithic-content-crash.html
new file mode 100644
index 0000000..1fb178f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-multicol/balance-extremely-tall-monolithic-content-crash.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://www.w3.org/TR/css-multicol-1/#filling-columns">
+<link rel="help" href="https://www.w3.org/TR/css-break-3/#monolithic">
+<div style="columns:2;">
+  <div style="contain:size; height:12345678901234px;"></div>
+  <div style="contain:size; height:12345678901234px;"></div>
+  <div style="contain:size; height:12345678901234px;"></div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-003-ref.html
new file mode 100644
index 0000000..0ea90d7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-003-ref.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
+<script src="support/selections.js"></script>
+<link rel="stylesheet" href="support/highlights.css">
+<style>
+    main {
+        font-size: 7em;
+        margin: 0.5em;
+    }
+    main::selection {
+        color: white;
+        background-color: green;
+    }
+</style>
+<p>Test passes if the text below is white on green.
+<main class="highlight_reftest">quick</main>
+<script>selectNodeContents(document.querySelector("main"));</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-003.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-003.html
new file mode 100644
index 0000000..803b4401
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-003.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Pseudo-Elements Test: highlight styling: custom properties are applicable properties in highlight pseudos</title>
+<link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-styling">
+<link rel="match" href="highlight-styling-003-ref.html">
+<meta name="assert" value="This test verifies that ::selection styles can set and reference custom properties.">
+<script src="support/selections.js"></script>
+<link rel="stylesheet" href="support/highlights.css">
+<style>
+    main {
+        font-size: 7em;
+        margin: 0.5em;
+    }
+    main::selection {
+        --x: green;
+        color: white;
+        background-color: var(--x);
+    }
+</style>
+<p>Test passes if the text below is white on green.
+<main class="highlight_reftest">quick</main>
+<script>selectNodeContents(document.querySelector("main"));</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-004-ref.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-004-ref.html
new file mode 100644
index 0000000..0ea90d7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-004-ref.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
+<script src="support/selections.js"></script>
+<link rel="stylesheet" href="support/highlights.css">
+<style>
+    main {
+        font-size: 7em;
+        margin: 0.5em;
+    }
+    main::selection {
+        color: white;
+        background-color: green;
+    }
+</style>
+<p>Test passes if the text below is white on green.
+<main class="highlight_reftest">quick</main>
+<script>selectNodeContents(document.querySelector("main"));</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-004.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-004.html
new file mode 100644
index 0000000..28d5bc0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/highlight-styling-004.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Pseudo-Elements Test: highlight styling: originating custom property values do not affect highlight pseudos</title>
+<link rel="author" title="Delan Azabani" href="mailto:dazabani@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#highlight-styling">
+<link rel="match" href="highlight-styling-004-ref.html">
+<meta name="assert" value="This test verifies that custom property values set in originating elements do not participate in the substitution of those properties in ::selection styles.">
+<script src="support/selections.js"></script>
+<link rel="stylesheet" href="support/highlights.css">
+<style>
+    main {
+        font-size: 7em;
+        margin: 0.5em;
+        --x: red;
+    }
+    main::selection {
+        color: white;
+        background-color: var(--x, green);
+    }
+</style>
+<p>Test passes if the text below is white on green.
+<main class="highlight_reftest">quick</main>
+<script>selectNodeContents(document.querySelector("main"));</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html
index def6adf..164ac27 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-loose.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html
index bc204f5..b6fc49e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-normal.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html
index cdb8398..ebf511b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cj-strict.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html
index c932cb4..89573871 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html
index 7816fb5..ccb5f951 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html
index 833e45e..7f9fdb8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-cpm-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html
index a8a6836..771635b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-loose.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html
index 364eddaa..eba1843 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-normal.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html
index 87cc6f6..c7e2d2a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-hyphens-strict.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt
deleted file mode 100644
index 4c1a998d..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL 2024  ONE DOT LEADER may appear at line start if ja and loose assert_true: expected true got false
-FAIL 2025  TWO DOT LEADER may appear at line start if ja and loose assert_true: expected true got false
-FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_true: expected true got false
-FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_true: expected true got false
-FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html
index 235d381..c45691a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html
index 7bdedd5..a92d53aa6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-normal.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html
index 58c05bb..ccbf08e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-strict.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html
index 49f51f4..9d9e241 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-loose.html
@@ -44,23 +44,19 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
-
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
-
 document.fonts.ready.then(validate);
 
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html
index 55f54ea8..1b88d22 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-normal.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html
index 1c2cd9a..f14d140d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-iteration-strict.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html
index 4d79a12..111c799 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html
index eb3003c2..21c2719 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html
index 08e16f26..bed89ef 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-po-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-loose.html
index fde2a3d..cb600df 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-loose.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if ja and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt
deleted file mode 100644
index 8432cf1..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-FAIL 20AC  EURO SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-FAIL 2116  NUMERO SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if ja and normal assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal.html
index d6f58cb..130889d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt
deleted file mode 100644
index 5319ad1..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-FAIL 20AC  EURO SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-FAIL 2116  NUMERO SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if ja and strict assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict.html
index 8265f91..6b83bda 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="ja">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if ja and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-loose.html
index c902bf7..0a76b933 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-loose.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if de and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-normal.html
index e98d4a2..a5339b4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-normal.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if de and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-strict.html
index 29810f2..ebfbed70 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cj-strict.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-loose.html
index 9dffd854..7937664 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-normal.html
index 9c0af13..0818c436 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-strict.html
index d573bac7..97d2cc6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-cpm-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-loose.html
index 0455915d..611c0617 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-loose.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-normal.html
index fc23481..f8ca7233 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-normal.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-strict.html
index bec4937..4cab0c4 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-hyphens-strict.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt
deleted file mode 100644
index ee73f7ad..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL 2024  ONE DOT LEADER may appear at line start if de and loose assert_true: expected true got false
-FAIL 2025  TWO DOT LEADER may appear at line start if de and loose assert_true: expected true got false
-FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_true: expected true got false
-FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_true: expected true got false
-FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose.html
index fff23f3..e1ea5c5 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if de and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-normal.html
index d000d8e..4230752 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-normal.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-strict.html
index 79d6e12c..9e9ff0c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-strict.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-loose.html
index ff8ef05..065820f2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-loose.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if de and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-normal.html
index c5913821..3124d5c 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-normal.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-strict.html
index 46c0fe3..774da5dc 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-iteration-strict.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-loose.html
index 0eec9685..e133b06 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-normal.html
index 6043912..8e3efaa 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-strict.html
index 8c9387f..00cc1e41 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-po-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if de and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-loose.html
index ba3581a7..5958365 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-loose.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if de and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-normal.html
index 477a779..28cbaf2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-normal.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if de and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-strict.html
index 4d4bee52..4a96c8f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-pr-strict.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="de">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if de and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-loose.html
index d6d0a1b..dd53abb1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-loose.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-normal.html
index 548fa17..faf8d40 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-normal.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict-expected.txt
index 5fa18c5a..34159ed 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict-expected.txt
@@ -1,55 +1,55 @@
 This is a testharness.js-based test.
 Found 51 tests; 0 PASS, 51 FAIL, 0 TIMEOUT, 0 NOTRUN.
-FAIL 3041  HIRAGANA LETTER SMALL A may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3043  HIRAGANA LETTER SMALL I may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3045  HIRAGANA LETTER SMALL U may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3047  HIRAGANA LETTER SMALL E may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3049  HIRAGANA LETTER SMALL O may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3063  HIRAGANA LETTER SMALL TU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3083  HIRAGANA LETTER SMALL YA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3085  HIRAGANA LETTER SMALL YU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3087  HIRAGANA LETTER SMALL YO may NOT appear at line start if strict assert_true: expected true got false
-FAIL 308E  HIRAGANA LETTER SMALL WA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3095  HIRAGANA LETTER SMALL KA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 3096  HIRAGANA LETTER SMALL KE may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30A1  KATAKANA LETTER SMALL A may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30A3  KATAKANA LETTER SMALL I may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30A5  KATAKANA LETTER SMALL U may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30A7  KATAKANA LETTER SMALL E may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30A9  KATAKANA LETTER SMALL O may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30C3  KATAKANA LETTER SMALL TU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30E3  KATAKANA LETTER SMALL YA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30E5  KATAKANA LETTER SMALL YU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30E7  KATAKANA LETTER SMALL YO may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30EE  KATAKANA LETTER SMALL WA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30F5  KATAKANA LETTER SMALL KA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30F6  KATAKANA LETTER SMALL KE may NOT appear at line start if strict assert_true: expected true got false
-FAIL 30FC  KATAKANA-HIRAGANA PROLONGED SOUND MARK may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F0  KATAKANA LETTER SMALL KU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F1  KATAKANA LETTER SMALL SI may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F2  KATAKANA LETTER SMALL SU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F3  KATAKANA LETTER SMALL TO may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F4  KATAKANA LETTER SMALL NU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F5  KATAKANA LETTER SMALL HA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F6  KATAKANA LETTER SMALL HI may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F7  KATAKANA LETTER SMALL HU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F8  KATAKANA LETTER SMALL HE may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31F9  KATAKANA LETTER SMALL HO may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31FA  KATAKANA LETTER SMALL MU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31FB  KATAKANA LETTER SMALL RA may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31FC  KATAKANA LETTER SMALL RI may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31FD  KATAKANA LETTER SMALL RU may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31FE  KATAKANA LETTER SMALL RE may NOT appear at line start if strict assert_true: expected true got false
-FAIL 31FF  KATAKANA LETTER SMALL RO may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF67  HALFWIDTH KATAKANA LETTER SMALL A may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF68  HALFWIDTH KATAKANA LETTER SMALL I may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF69  HALFWIDTH KATAKANA LETTER SMALL U may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF6A  HALFWIDTH KATAKANA LETTER SMALL E may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF6B  HALFWIDTH KATAKANA LETTER SMALL O may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF6C  HALFWIDTH KATAKANA LETTER SMALL YA may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF6D  HALFWIDTH KATAKANA LETTER SMALL YU may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF6E  HALFWIDTH KATAKANA LETTER SMALL YO may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF6F  HALFWIDTH KATAKANA LETTER SMALL TU may NOT appear at line start if strict assert_true: expected true got false
-FAIL FF70  HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK may NOT appear at line start if strict assert_true: expected true got false
+FAIL 3041  HIRAGANA LETTER SMALL A may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3043  HIRAGANA LETTER SMALL I may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3045  HIRAGANA LETTER SMALL U may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3047  HIRAGANA LETTER SMALL E may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3049  HIRAGANA LETTER SMALL O may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3063  HIRAGANA LETTER SMALL TU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3083  HIRAGANA LETTER SMALL YA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3085  HIRAGANA LETTER SMALL YU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3087  HIRAGANA LETTER SMALL YO may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 308E  HIRAGANA LETTER SMALL WA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3095  HIRAGANA LETTER SMALL KA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 3096  HIRAGANA LETTER SMALL KE may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30A1  KATAKANA LETTER SMALL A may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30A3  KATAKANA LETTER SMALL I may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30A5  KATAKANA LETTER SMALL U may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30A7  KATAKANA LETTER SMALL E may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30A9  KATAKANA LETTER SMALL O may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30C3  KATAKANA LETTER SMALL TU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30E3  KATAKANA LETTER SMALL YA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30E5  KATAKANA LETTER SMALL YU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30E7  KATAKANA LETTER SMALL YO may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30EE  KATAKANA LETTER SMALL WA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30F5  KATAKANA LETTER SMALL KA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30F6  KATAKANA LETTER SMALL KE may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 30FC  KATAKANA-HIRAGANA PROLONGED SOUND MARK may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F0  KATAKANA LETTER SMALL KU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F1  KATAKANA LETTER SMALL SI may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F2  KATAKANA LETTER SMALL SU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F3  KATAKANA LETTER SMALL TO may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F4  KATAKANA LETTER SMALL NU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F5  KATAKANA LETTER SMALL HA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F6  KATAKANA LETTER SMALL HI may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F7  KATAKANA LETTER SMALL HU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F8  KATAKANA LETTER SMALL HE may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31F9  KATAKANA LETTER SMALL HO may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31FA  KATAKANA LETTER SMALL MU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31FB  KATAKANA LETTER SMALL RA may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31FC  KATAKANA LETTER SMALL RI may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31FD  KATAKANA LETTER SMALL RU may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31FE  KATAKANA LETTER SMALL RE may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL 31FF  KATAKANA LETTER SMALL RO may NOT appear at line start if strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF67  HALFWIDTH KATAKANA LETTER SMALL A may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF68  HALFWIDTH KATAKANA LETTER SMALL I may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF69  HALFWIDTH KATAKANA LETTER SMALL U may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF6A  HALFWIDTH KATAKANA LETTER SMALL E may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF6B  HALFWIDTH KATAKANA LETTER SMALL O may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF6C  HALFWIDTH KATAKANA LETTER SMALL YA may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF6D  HALFWIDTH KATAKANA LETTER SMALL YU may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF6E  HALFWIDTH KATAKANA LETTER SMALL YO may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF6F  HALFWIDTH KATAKANA LETTER SMALL TU may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
+FAIL FF70  HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK may NOT appear at line start if strict assert_approx_equals: expected 84 +/- 1 but got 54
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict.html
index a4e87178..855d271a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cj-strict.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-loose.html
index 3d4cb26..78358251 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
-    }, lines[i]+' may NOT appear at line start if lang unknonw loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
+    }, lines[i]+' may NOT appear at line start if lang unknown and loose');
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-normal.html
index 417973b..128d600 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if lang unknown and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-strict.html
index c6685dfe..d13307d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-cpm-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if lang unknown and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-loose.html
index ab9624fd..2cd6e72 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-loose.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if lang unknown and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-normal.html
index a20e244..c506a0d6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-normal.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
-    }, lines[i]+' may NOT appear at line start if lang unkonwn and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
+    }, lines[i]+' may NOT appear at line start if lang unknown and normal');
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-strict.html
index 3f2e04c..22b07b8 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-hyphens-strict.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if lang unknown and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt
deleted file mode 100644
index c4135676..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL 2024  ONE DOT LEADER may appear at line start if loose assert_true: expected true got false
-FAIL 2025  TWO DOT LEADER may appear at line start if loose assert_true: expected true got false
-FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if loose assert_true: expected true got false
-FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if loose assert_true: expected true got false
-FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if loose assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose.html
index c507f78e..f724244 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-normal.html
index 4e8d961..e86775d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-normal.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-strict.html
index a1c3a85..92e6c5d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-strict.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose-expected.txt
index 6d7a0fb..4a37e5d6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose-expected.txt
@@ -1,9 +1,9 @@
 This is a testharness.js-based test.
-FAIL 3005  IDEOGRAPHIC ITERATION MARK may appear at line start if lang unknown and loose assert_true: expected true got false
-FAIL 303B  VERTICAL IDEOGRAPHIC ITERATION MARK may appear at line start if lang unknown and loose assert_true: expected true got false
-FAIL 309D  HIRAGANA ITERATION MARK may appear at line start if lang unknown and loose assert_true: expected true got false
-FAIL 309E  HIRAGANA VOICED ITERATION MARK may appear at line start if lang unknown and loose assert_true: expected true got false
-FAIL 30FD  KATAKANA ITERATION MARK may appear at line start if lang unknown and loose assert_true: expected true got false
-FAIL 30FE  KATAKANA VOICED ITERATION MARK may appear at line start if lang unknown and loose assert_true: expected true got false
+FAIL 3005  IDEOGRAPHIC ITERATION MARK may appear at line start if lang unknown and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 303B  VERTICAL IDEOGRAPHIC ITERATION MARK may appear at line start if lang unknown and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 309D  HIRAGANA ITERATION MARK may appear at line start if lang unknown and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 309E  HIRAGANA VOICED ITERATION MARK may appear at line start if lang unknown and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 30FD  KATAKANA ITERATION MARK may appear at line start if lang unknown and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 30FE  KATAKANA VOICED ITERATION MARK may appear at line start if lang unknown and loose assert_approx_equals: expected 69 +/- 1 but got 99
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose.html
index 420a7b6..29d8585 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-loose.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if lang unknown and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-normal.html
index 9d7b2c03..c5e2937 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-normal.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if lang unknown and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-strict.html
index 54c7559..2fe1cf0 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-iteration-strict.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if lang unknown and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-loose.html
index e635075a..b268666 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-normal.html
index 46e7472..d50c8b3 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-strict.html
index 61fd7b7..0f1420d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-po-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-loose.html
index 97be026..e966da2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-loose.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-normal.html
index 4e30c4e..1ae3a6e 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-normal.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-strict.html
index b8d0fa5..7dddd5f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-pr-strict.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-loose.html
index a131395e..2b65c2d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-loose.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-normal.html
index ff7456b8..adda199 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-normal.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-strict.html
index dc752f1..bbae688 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cj-strict.html
@@ -89,10 +89,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -102,10 +98,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html
index 4044e106..38c207db 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html
index 01096b2..edeb465b1 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html
index 8460aaa..235bd712 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-cpm-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html
index 103d8afd..5d4ab12 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-loose.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html
index 5481b824..1a07353 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-normal.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html
index bf61555a..8ac874e2 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-hyphens-strict.html
@@ -40,10 +40,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -53,10 +49,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt
deleted file mode 100644
index ec0cad2a..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-FAIL 2024  ONE DOT LEADER may appear at line start if zh and loose assert_true: expected true got false
-FAIL 2025  TWO DOT LEADER may appear at line start if zh and loose assert_true: expected true got false
-FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_true: expected true got false
-FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_true: expected true got false
-FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html
index e768661..56fec0b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html
index a9409cf..67d1668 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-normal.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html
index defdf22..a03f8fec 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-strict.html
@@ -43,10 +43,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -56,10 +52,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html
index 64f8219..6ac29a1fb 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-loose.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html
index a7f66ea2..8f5276ac 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-normal.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html
index 0b1ca2a..678e43d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-iteration-strict.html
@@ -44,10 +44,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -57,10 +53,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html
index 04a0f4d6..3bd1b2f 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-loose.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html
index 5a52cf8..76eed4b 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-normal.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html
index d85b74a54..991b9ff 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-po-strict.html
@@ -48,10 +48,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -61,10 +57,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-loose.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-loose.html
index b56cd28c..e3b13e06 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-loose.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-loose.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文文<br/>&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may appear at line start if zh and loose');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt
deleted file mode 100644
index 0dd73724..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-FAIL 20AC  EURO SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-FAIL 2116  NUMERO SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if zh and normal assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal.html
index 198bf28c..954953cd 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and normal');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt
deleted file mode 100644
index 5d9d42c5..0000000
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-FAIL 20AC  EURO SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-FAIL 2116  NUMERO SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if zh and strict assert_true: expected true got false
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict.html b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict.html
index c71014b4..cefd429 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict.html
@@ -46,10 +46,6 @@
 	 '<div class="ref" id="ref'+i+'" lang="zh">文文文文文<br/>文&#x'+hex+';字<span id="refSpan'+i+'">字</span></div>' +
 	 '</div>'
 	}
-function spansNearEnough(counter) {
-  return Math.abs( document.getElementById('testSpan'+counter).getBoundingClientRect().left
-           - document.getElementById('refSpan'+counter).getBoundingClientRect().left ) < 1;
-}
 
 document.querySelector('body').innerHTML = out
 setup({explicit_done: true});
@@ -59,10 +55,12 @@
 function validate() {
   for (i=0;i<lines.length;i++) {
     test(function() {
-      assert_true(spansNearEnough(i));
+      assert_approx_equals(
+        document.getElementById('testSpan'+i).getBoundingClientRect().left,
+        document.getElementById('refSpan'+i).getBoundingClientRect().left, 1);
+      // Hide successful tests.
+      document.getElementById('test'+i).parentNode.style.display = 'none';
     }, lines[i]+' may NOT appear at line start if zh and strict');
-    // Hide successful tests.
-    if (spansNearEnough(i)) document.getElementById('test'+i).parentNode.style.display = 'none'
   }
   done();
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/tab-size/tab-size-block-ancestor-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/tab-size/tab-size-block-ancestor-ref.html
new file mode 100644
index 0000000..bb1cdc93a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/tab-size/tab-size-block-ancestor-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text reference</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<style>
+div {
+    font: 16px monospace;
+    white-space: pre;
+}
+b {
+    font: bold 16px monospace;
+}
+</style>
+
+<p>Test passes if the five “A” letters below are vertically aligned with each other.
+
+<div>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>A</b>
+</div>
+<div>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>A</b>
+</div>
+<div>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>A</b>
+</div>
+<div>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>A</b>
+</div>
+<div>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>A</b>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/tab-size/tab-size-block-ancestor.html b/third_party/blink/web_tests/external/wpt/css/css-text/tab-size/tab-size-block-ancestor.html
new file mode 100644
index 0000000..b295382
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/tab-size/tab-size-block-ancestor.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text level 3 Test: tab-size based on block ancestor's space</title>
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#tab-size-property">
+<link rel="match" href="tab-size-block-ancestor-ref.html">
+<meta name="assert" content="tab width is based on space character in the block ancestor">
+<style>
+div {
+    font: 16px monospace;
+    white-space: pre;
+    tab-size: 10;
+}
+.test1 span {
+    font-size: 1px;
+}
+.test2 span {
+    font-size: 10px;
+}
+.test3 span {
+    tab-size: 5;
+}
+.test4 span {
+    font-size: 10px;
+    tab-size: 2.5;
+}
+b {
+    font: bold 16px monospace;
+}
+</style>
+
+<p>Test passes if the five “A” letters below are vertically aligned with each other.
+
+<div>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>A</b><!-- indented by 10 spaces -->
+</div>
+<div class=test1>
+<span>&#9;<b>A</b></span>
+</div>
+<div class=test2>
+<span>&#9;<b>A</b></span>
+</div>
+<div class=test3>
+<span>&#9;&#9;<b>A</b></span>
+</div>
+<div class=test4>
+<span>&#9;&#9;&#9;&#9;<b>A</b></span>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-auto-non-html-namespace-001.html b/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-auto-non-html-namespace-001.html
new file mode 100644
index 0000000..892e0da6
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/appearance-auto-non-html-namespace-001.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>CSS Basic User Interface Test: appearance: auto on elements in non-HTML namespace</title>
+<link rel="match" href="nothing-below-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#appearance-switching">
+<meta name="assert" content="appearance: auto should have no effect on non-HTML elements.">
+<style>
+  div * { appearance: auto; display: inline-block; width: 1em; height: 1em; }
+</style>
+<p>There should be nothing below:</p>
+<div id=div></div>
+<script>
+for (var tagName of ['button', 'input', 'meter', 'progress', 'select', 'textarea']) {
+  div.appendChild(document.createElementNS('not-html', tagName));
+}
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/nothing-below-ref.html b/third_party/blink/web_tests/external/wpt/css/css-ui/nothing-below-ref.html
new file mode 100644
index 0000000..c8d6508
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/nothing-below-ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<title>CSS Basic User Interface Reference: nothing below</title>
+<p>There should be nothing below:</p>
diff --git a/third_party/blink/web_tests/external/wpt/editing/crashtests/inserthorizontalrule-in-fieldset-and-everything-styled-white-space-pre.html b/third_party/blink/web_tests/external/wpt/editing/crashtests/inserthorizontalrule-in-fieldset-and-everything-styled-white-space-pre.html
new file mode 100644
index 0000000..d06157e7
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/editing/crashtests/inserthorizontalrule-in-fieldset-and-everything-styled-white-space-pre.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        * {
+            white-space: pre
+        }
+    </style>
+    <script>
+      document.addEventListener('DOMContentLoaded', () => {
+        const quote_0 = document.getElementById('id_0')
+        const quote_1 = document.createElement('blockquote')
+        const fieldset_1 = document.createElement('fieldset')
+        quote_1.appendChild(fieldset_1)
+        document.documentElement.appendChild(quote_1)
+        const selection = self.getSelection()
+        selection.collapse(fieldset_1, 0)
+        quote_0.contentEditable = false
+        document.documentElement.contentEditable = true
+        document.execCommand('insertHorizontalRule', false, null)
+      })
+    </script>
+</head>
+<blockquote id='id_0'></blockquote>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/editing/crashtests/justifyfull-selection-containing-non-editable-div-and-everything-styled-white-space-break-space.html b/third_party/blink/web_tests/external/wpt/editing/crashtests/justifyfull-selection-containing-non-editable-div-and-everything-styled-white-space-break-space.html
new file mode 100644
index 0000000..cf199fa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/editing/crashtests/justifyfull-selection-containing-non-editable-div-and-everything-styled-white-space-break-space.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <style>
+        * {
+            white-space: break-spaces ! important;
+        }
+    </style>
+    <script>
+      window.addEventListener('load', () => {
+        document.documentElement.contentEditable = true
+        document.execCommand('selectAll', false, null)
+        document.execCommand('justifyFull', false, null)
+      })
+    </script>
+</head>
+<div contenteditable='false'></div>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/delete.js b/third_party/blink/web_tests/external/wpt/editing/data/delete.js
index 5e36c55..183451e 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/delete.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/delete.js
@@ -2437,42 +2437,42 @@
     {"defaultparagraphseparator":[false,false,"div",false,false,"p"],"delete":[false,false,"",false,false,""]}],
 ["<p><b>[foo]</b>",
     [["delete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<p><quasit>[foo]</quasit>",
     [["delete",""]],
-    "<p><quasit>{}<br></quasit></p>",
+    "<p>{}<br></p>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<p><b><i>[foo]</i></b>",
     [["delete",""]],
-    "<p><b><i>{}<br></i></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<p><b>{foo}</b>",
     [["delete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<p>{<b>foo</b>}",
     [["delete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<p><b>f[]</b>",
     [["delete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<b>[foo]</b>",
     [["delete",""]],
-    "<b>{}<br></b>",
+    "{}<br>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<div><b>[foo]</b></div>",
     [["delete",""]],
-    "<div><b>{}<br></b></div>",
+    "<div>{}<br></div>",
     [true],
     {"delete":[false,false,"",false,false,""]}],
 ["<div><div><p>foo</p></div></div><div></div><div><div>[]bar</div></div></div>",
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js b/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js
index ffd7dad..cc03bcd 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/forwarddelete.js
@@ -2322,42 +2322,42 @@
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<p><b>[foo]</b>",
     [["forwarddelete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<p><quasit>[foo]</quasit>",
     [["forwarddelete",""]],
-    "<p><quasit>{}<br></quasit></p>",
+    "<p>{}<br></p>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<p><b><i>[foo]</i></b>",
     [["forwarddelete",""]],
-    "<p><b><i>{}<br></i></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<p><b>{foo}</b>",
     [["forwarddelete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<p>{<b>foo</b>}",
     [["forwarddelete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<p><b>[]f</b>",
     [["forwarddelete",""]],
-    "<p><b>{}<br></b></p>",
+    "<p>{}<br></p>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<b>[foo]</b>",
     [["forwarddelete",""]],
-    "<b>{}<br></b>",
+    "{}<br>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<div><b>[foo]</b></div>",
     [["forwarddelete",""]],
-    "<div><b>{}<br></b></div>",
+    "<div>{}<br></div>",
     [true],
     {"forwarddelete":[false,false,"",false,false,""]}],
 ["<div><div><p>foo[]</p></div></div><div></div><div><div>bar</div></div></div>",
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/multitest.js b/third_party/blink/web_tests/external/wpt/editing/data/multitest.js
index 338b9c9..47e5849 100644
--- a/third_party/blink/web_tests/external/wpt/editing/data/multitest.js
+++ b/third_party/blink/web_tests/external/wpt/editing/data/multitest.js
@@ -2414,5 +2414,45 @@
     [["delete",""],["inserttext","a"]],
     "<blockquote><font color=\"blue\">a[]</font></blockquote>",
     [true,true],
-    {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}]
+    {"delete":[false,false,"",false,false,""],"inserttext":[false,false,"",false,false,""]}],
+["<div><b>[abc]</b></div>",
+    [["styleWithCSS", "false"],["delete",""],["inserttext","a"]],
+    ["<div><b>a</b></div>",
+     "<div><b>a</b><br></div>"],
+    [true,true,true],
+    {"bold":[false,true,"",false,true,""]}],
+["<div>abc<b>[def]</b></div>",
+    [["styleWithCSS", "false"],["delete",""],["inserttext","d"]],
+    ["<div>abc<b>d</b></div>",
+     "<div>abc<b>d</b><br></div>"],
+    [true,true,true],
+    {"bold":[false,true,"",false,true,""]}],
+["<div><b>[abc]</b></div>",
+    [["styleWithCSS", "false"],["delete",""],["insertparagraph",""],["inserttext","a"]],
+    ["<div><br></div><div><b>a</b></div>",
+     "<div><br></div><div><b>a</b><br></div>"],
+    [true,true,true,true],
+    {"bold":[false,true,"",false,true,""]}],
+["<div>abc<b>[def]</b></div>",
+    [["styleWithCSS", "false"], ["delete",""],["insertparagraph",""],["inserttext","d"]],
+    ["<div>abc</div><div><b>d</b></div>",
+     "<div>abc</div><div><b>d</b><br></div>",
+     "<div>abc<br></div><div><b>d</b></div>",
+     "<div>abc<br></div><div><b>d</b><br></div>"],
+    [true,true,true,true],
+    {"bold":[false,true,"",false,true,""]}],
+["<div><b>[abc]</b></div>",
+    [["styleWithCSS", "false"],["insertparagraph",""],["inserttext","a"]],
+    ["<div><br></div><div><b>a</b></div>",
+     "<div><br></div><div><b>a</b><br></div>"],
+    [true,true,true],
+    {"bold":[false,true,"",false,true,""]}],
+["<div>abc<b>[def]</b></div>",
+    [["styleWithCSS", "false"],["insertparagraph",""],["inserttext","d"]],
+    ["<div>abc</div><div><b>d</b></div>",
+     "<div>abc</div><div><b>d</b><br></div>",
+     "<div>abc<br></div><div><b>d</b></div>",
+     "<div>abc<br></div><div><b>d</b><br></div>"],
+    [true,true,true],
+    {"bold":[false,true,"",false,true,""]}],
 ]
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative-expected.txt
index 989dab8..7bcb233f 100644
--- a/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative-expected.txt
@@ -1,57 +1,75 @@
 This is a testharness.js-based test.
-Found 54 tests; 32 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 72 tests; 40 PASS, 32 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS Inserting paragraph when selection is collapsed in <br> in <div> which is only child
+PASS Inserting paragraph when selection is collapsed in <br> in <div> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <br> which follows a text node in <div>
 PASS Inserting paragraph when selection is collapsed in <br> which is followed by a text node in <div>
 FAIL Inserting paragraph when selection is collapsed in <embed> in <div> which is only child assert_in_array: The paragraph should be inserted before the <embed> element value "<div><embed></div>" not in array ["<div><br></div><div><embed></div>", "<div><br></div><div><embed><br></div>"]
+FAIL Inserting paragraph when selection is collapsed in <embed> in <div> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <embed> element value "<div><embed></div>" not in array ["<div><br></div><div><embed></div>", "<div><br></div><div><embed><br></div>"]
 FAIL Inserting paragraph when selection is collapsed in <embed> which follows a text node in <div> assert_in_array: The paragraph should be split before the <embed> element value "<div>abc<embed></div><div><br></div>" not in array ["<div>abc</div><div><embed></div>", "<div>abc<br></div><div><embed></div>", "<div>abc</div><div><embed><br></div>", "<div>abc<br></div><div><embed><br></div>"]
 PASS Inserting paragraph when selection is collapsed in <embed> which is followed by a text node in <div>
 FAIL Inserting paragraph when selection is collapsed in <hr> in <div> which is only child assert_in_array: The paragraph should be inserted before the <hr> element value "<div><br><hr></div>" not in array ["<div><br></div><div><hr></div>", "<div><br></div><div><hr><br></div>"]
+FAIL Inserting paragraph when selection is collapsed in <hr> in <div> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <hr> element value "<div><br><hr></div>" not in array ["<div><br></div><div><hr></div>", "<div><br></div><div><hr><br></div>"]
 FAIL Inserting paragraph when selection is collapsed in <hr> which follows a text node in <div> assert_in_array: The paragraph should be split before the <hr> element value "<div>abc<br><br><hr></div>" not in array ["<div>abc</div><div><hr></div>", "<div>abc<br></div><div><hr></div>", "<div>abc</div><div><hr><br></div>", "<div>abc<br></div><div><hr><br></div>"]
 FAIL Inserting paragraph when selection is collapsed in <hr> which is followed by a text node in <div> assert_in_array: The paragraph should be inserted before the <hr> element value "<div><br><hr>abc</div>" not in array ["<div><br></div><div><hr>abc</div>", "<div><br></div><div><hr>abc<br></div>"]
 PASS Inserting paragraph when selection is collapsed in <img> in <div> which is only child
+PASS Inserting paragraph when selection is collapsed in <img> in <div> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <img> which follows a text node in <div>
 PASS Inserting paragraph when selection is collapsed in <img> which is followed by a text node in <div>
 PASS Inserting paragraph when selection is collapsed in <input> in <div> which is only child
+PASS Inserting paragraph when selection is collapsed in <input> in <div> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <input> which follows a text node in <div>
 PASS Inserting paragraph when selection is collapsed in <input> which is followed by a text node in <div>
 FAIL Inserting paragraph when selection is collapsed in <wbr> in <div> which is only child assert_in_array: The paragraph should be inserted before the <wbr> element value "<div><wbr></div><div><br></div>" not in array ["<div><br></div><div><wbr></div>", "<div><br></div><div><wbr><br></div>"]
+FAIL Inserting paragraph when selection is collapsed in <wbr> in <div> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <wbr> element value "<div><wbr></div><div><br></div>" not in array ["<div><br></div><div><wbr></div>", "<div><br></div><div><wbr><br></div>"]
 FAIL Inserting paragraph when selection is collapsed in <wbr> which follows a text node in <div> assert_in_array: The paragraph should be split before the <wbr> element value "<div>abc<wbr></div><div><br></div>" not in array ["<div>abc</div><div><wbr></div>", "<div>abc<br></div><div><wbr></div>", "<div>abc</div><div><wbr><br></div>", "<div>abc<br></div><div><wbr><br></div>"]
 PASS Inserting paragraph when selection is collapsed in <wbr> which is followed by a text node in <div>
 PASS Inserting paragraph when selection is collapsed in <br> in <h1> which is only child
+PASS Inserting paragraph when selection is collapsed in <br> in <h1> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <br> which follows a text node in <h1>
 PASS Inserting paragraph when selection is collapsed in <br> which is followed by a text node in <h1>
 FAIL Inserting paragraph when selection is collapsed in <embed> in <h1> which is only child assert_in_array: The paragraph should be inserted before the <embed> element value "<h1><embed></h1>" not in array ["<h1><br></h1><div><embed></div>", "<h1><br></h1><div><embed><br></div>"]
+FAIL Inserting paragraph when selection is collapsed in <embed> in <h1> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <embed> element value "<h1><embed></h1>" not in array ["<h1><br></h1><div><embed></div>", "<h1><br></h1><div><embed><br></div>"]
 FAIL Inserting paragraph when selection is collapsed in <embed> which follows a text node in <h1> assert_in_array: The paragraph should be split before the <embed> element value "<h1>abc<embed></h1><div><br></div>" not in array ["<h1>abc</h1><div><embed></div>", "<h1>abc<br></h1><div><embed></div>", "<h1>abc</h1><div><embed><br></div>", "<h1>abc<br></h1><div><embed><br></div>"]
 PASS Inserting paragraph when selection is collapsed in <embed> which is followed by a text node in <h1>
 FAIL Inserting paragraph when selection is collapsed in <hr> in <h1> which is only child assert_in_array: The paragraph should be inserted before the <hr> element value "<h1><br><hr></h1>" not in array ["<h1><br></h1><h1><hr></h1>", "<h1><br></h1><h1><hr><br></h1>"]
+FAIL Inserting paragraph when selection is collapsed in <hr> in <h1> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <hr> element value "<h1><br><hr></h1>" not in array ["<h1><br></h1><h1><hr></h1>", "<h1><br></h1><h1><hr><br></h1>"]
 FAIL Inserting paragraph when selection is collapsed in <hr> which follows a text node in <h1> assert_in_array: The paragraph should be split before the <hr> element value "<h1>abc<br><br><hr></h1>" not in array ["<h1>abc</h1><h1><hr></h1>", "<h1>abc<br></h1><h1><hr></h1>", "<h1>abc</h1><h1><hr><br></h1>", "<h1>abc<br></h1><h1><hr><br></h1>"]
 FAIL Inserting paragraph when selection is collapsed in <hr> which is followed by a text node in <h1> assert_in_array: The paragraph should be inserted before the <hr> element value "<h1><br><hr>abc</h1>" not in array ["<h1><br></h1><h1><hr>abc</h1>", "<h1><br></h1><h1><hr>abc<br></h1>"]
 PASS Inserting paragraph when selection is collapsed in <img> in <h1> which is only child
+PASS Inserting paragraph when selection is collapsed in <img> in <h1> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <img> which follows a text node in <h1>
 PASS Inserting paragraph when selection is collapsed in <img> which is followed by a text node in <h1>
 PASS Inserting paragraph when selection is collapsed in <input> in <h1> which is only child
+PASS Inserting paragraph when selection is collapsed in <input> in <h1> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <input> which follows a text node in <h1>
 PASS Inserting paragraph when selection is collapsed in <input> which is followed by a text node in <h1>
 FAIL Inserting paragraph when selection is collapsed in <wbr> in <h1> which is only child assert_in_array: The paragraph should be inserted before the <wbr> element value "<h1><wbr></h1><div><br></div>" not in array ["<h1><br></h1><div><wbr></div>", "<h1><br></h1><div><wbr><br></div>"]
+FAIL Inserting paragraph when selection is collapsed in <wbr> in <h1> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <wbr> element value "<h1><wbr></h1><div><br></div>" not in array ["<h1><br></h1><div><wbr></div>", "<h1><br></h1><div><wbr><br></div>"]
 FAIL Inserting paragraph when selection is collapsed in <wbr> which follows a text node in <h1> assert_in_array: The paragraph should be split before the <wbr> element value "<h1>abc<wbr></h1><div><br></div>" not in array ["<h1>abc</h1><div><wbr></div>", "<h1>abc<br></h1><div><wbr></div>", "<h1>abc</h1><div><wbr><br></div>", "<h1>abc<br></h1><div><wbr><br></div>"]
 PASS Inserting paragraph when selection is collapsed in <wbr> which is followed by a text node in <h1>
 FAIL Inserting paragraph when selection is collapsed in <br> in <li> which is only child assert_in_array: The paragraph should be inserted before the <br> element value "<div><br></div>" not in array "<ol><li><br></li><li><br></li></ol>"
+FAIL Inserting paragraph when selection is collapsed in <br> in <li> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <br> element value "<div><br></div>" not in array "<ol><li><br></li><li><br></li></ol>"
 PASS Inserting paragraph when selection is collapsed in <br> which follows a text node in <li>
 PASS Inserting paragraph when selection is collapsed in <br> which is followed by a text node in <li>
 FAIL Inserting paragraph when selection is collapsed in <embed> in <li> which is only child assert_in_array: The paragraph should be inserted before the <embed> element value "<div><br></div>" not in array ["<ol><li><br></li><li><embed></li></ol>", "<ol><li><br></li><li><embed><br></li></ol>"]
+FAIL Inserting paragraph when selection is collapsed in <embed> in <li> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <embed> element value "<div><br></div>" not in array ["<ol><li><br></li><li><embed></li></ol>", "<ol><li><br></li><li><embed><br></li></ol>"]
 FAIL Inserting paragraph when selection is collapsed in <embed> which follows a text node in <li> assert_in_array: The paragraph should be split before the <embed> element value "<ol><li>abc<embed></li><li><br></li></ol>" not in array ["<ol><li>abc</li><li><embed></li></ol>", "<ol><li>abc<br></li><li><embed></li></ol>", "<ol><li>abc</li><li><embed><br></li></ol>", "<ol><li>abc<br></li><li><embed><br></li></ol>"]
 PASS Inserting paragraph when selection is collapsed in <embed> which is followed by a text node in <li>
 FAIL Inserting paragraph when selection is collapsed in <hr> in <li> which is only child assert_in_array: The paragraph should be inserted before the <hr> element value "<ol><li><br><hr></li></ol>" not in array ["<ol><li><br></li><li><hr></li></ol>", "<ol><li><br></li><li><hr><br></li></ol>"]
+FAIL Inserting paragraph when selection is collapsed in <hr> in <li> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <hr> element value "<ol><li><br><hr></li></ol>" not in array ["<ol><li><br></li><li><hr></li></ol>", "<ol><li><br></li><li><hr><br></li></ol>"]
 FAIL Inserting paragraph when selection is collapsed in <hr> which follows a text node in <li> assert_in_array: The paragraph should be split before the <hr> element value "<ol><li>abc<br><br><hr></li></ol>" not in array ["<ol><li>abc</li><li><hr></li></ol>", "<ol><li>abc<br></li><li><hr></li></ol>", "<ol><li>abc</li><li><hr><br></li></ol>", "<ol><li>abc<br></li><li><hr><br></li></ol>"]
 FAIL Inserting paragraph when selection is collapsed in <hr> which is followed by a text node in <li> assert_in_array: The paragraph should be inserted before the <hr> element value "<ol><li><br><hr>abc</li></ol>" not in array ["<ol><li><br></li><li><hr>abc</li></ol>", "<ol><li><br></li><li><hr>abc<br></li></ol>"]
 PASS Inserting paragraph when selection is collapsed in <img> in <li> which is only child
+PASS Inserting paragraph when selection is collapsed in <img> in <li> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <img> which follows a text node in <li>
 PASS Inserting paragraph when selection is collapsed in <img> which is followed by a text node in <li>
 PASS Inserting paragraph when selection is collapsed in <input> in <li> which is only child
+PASS Inserting paragraph when selection is collapsed in <input> in <li> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting paragraph when selection is collapsed in <input> which follows a text node in <li>
 PASS Inserting paragraph when selection is collapsed in <input> which is followed by a text node in <li>
 FAIL Inserting paragraph when selection is collapsed in <wbr> in <li> which is only child assert_in_array: The paragraph should be inserted before the <wbr> element value "<div><br></div>" not in array ["<ol><li><br></li><li><wbr></li></ol>", "<ol><li><br></li><li><wbr><br></li></ol>"]
+FAIL Inserting paragraph when selection is collapsed in <wbr> in <li> which is only child (explicitly flushes maybe pending layout) assert_in_array: The paragraph should be inserted before the <wbr> element value "<div><br></div>" not in array ["<ol><li><br></li><li><wbr></li></ol>", "<ol><li><br></li><li><wbr><br></li></ol>"]
 FAIL Inserting paragraph when selection is collapsed in <wbr> which follows a text node in <li> assert_in_array: The paragraph should be split before the <wbr> element value "<ol><li>abc<wbr></li><li><br></li></ol>" not in array ["<ol><li>abc</li><li><wbr></li></ol>", "<ol><li>abc<br></li><li><wbr></li></ol>", "<ol><li>abc</li><li><wbr><br></li></ol>", "<ol><li>abc<br></li><li><wbr><br></li></ol>"]
 PASS Inserting paragraph when selection is collapsed in <wbr> which is followed by a text node in <li>
 Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative.html b/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative.html
index a9ecfdc..c4f788a 100644
--- a/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/editing/other/insert-paragraph-in-void-element.tentative.html
@@ -90,6 +90,49 @@
     }, `Inserting paragraph when selection is collapsed in <${tag}> in <${container}> which is only child`);
 
     test(() => {
+      editor.innerHTML = `${openTagOfContainer}<${tag}>${closeTagOfContainer}`;
+      const element = editor.querySelector(tag);
+      editor.focus();
+      const selection = getSelection();
+      selection.collapse(element, 0);
+      element.getBoundingClientRect();
+      document.execCommand("insertParagraph");
+      if (tag == "br") {
+        if (!visibleTag && container == "h1") {
+          assert_in_array(
+            editor.innerHTML,
+            `${openTagOfContainer}<br>${closeTagOfContainer}<div><br></div>`,
+            `The paragraph should be inserted before the <${tag}> element`
+          );
+        } else {
+          assert_in_array(
+            editor.innerHTML,
+            `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<br>${closeTagOfContainer}`,
+            `The paragraph should be inserted before the <${tag}> element`
+          );
+        }
+      } else if (!visibleTag && container == "h1") {
+        assert_in_array(
+          editor.innerHTML,
+          [
+            `${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}></div>`,
+            `${openTagOfContainer}<br>${closeTagOfContainer}<div><${tag}><br></div>`,
+          ],
+          `The paragraph should be inserted before the <${tag}> element`
+        );
+      } else {
+        assert_in_array(
+          editor.innerHTML,
+          [
+            `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}>${closeTagOfContainer}`,
+            `${openTagOfContainer}<br>${closeAndOpenTagsOfSplitPoint}<${tag}><br>${closeTagOfContainer}`,
+          ],
+          `The paragraph should be inserted before the <${tag}> element`
+        );
+      }
+    }, `Inserting paragraph when selection is collapsed in <${tag}> in <${container}> which is only child (explicitly flushes maybe pending layout)`);
+
+    test(() => {
       editor.innerHTML = `${openTagOfContainer}abc<${tag}>${closeTagOfContainer}`;
       const element = editor.querySelector(tag);
       editor.focus();
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative-expected.txt
index 9cbdf93..c287839 100644
--- a/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative-expected.txt
@@ -1,5 +1,6 @@
 This is a testharness.js-based test.
 PASS Inserting text when selection is collapsed in <br> which is only child
+PASS Inserting text when selection is collapsed in <br> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting text when selection is collapsed in <br> which follows a text node
 PASS Inserting text when selection is collapsed in <br> which is followed by a text node
 PASS Inserting text when selection is collapsed in <br> which follows an empty <span> element
@@ -7,6 +8,7 @@
 PASS Inserting text when selection is collapsed in <br> which follows a non-empty <span> element
 PASS Inserting text when selection is collapsed in <br> which follows a text node, an empty <span> element and white-space only text node
 FAIL Inserting text when selection is collapsed in <embed> which is only child assert_in_array: The text should be inserted before the <embed> element value "<div><embed></div>" not in array ["<div>abc<embed></div>", "<div>abc<embed><br></div>"]
+FAIL Inserting text when selection is collapsed in <embed> which is only child (explicitly flushes maybe pending layout) assert_in_array: The text should be inserted before the <embed> element value "<div><embed></div>" not in array ["<div>abc<embed></div>", "<div>abc<embed><br></div>"]
 PASS Inserting text when selection is collapsed in <embed> which follows a text node
 FAIL Inserting text when selection is collapsed in <embed> which is followed by a text node assert_in_array: The text should be inserted before the <embed> element value "<div><embed>abcdef</div>" not in array ["<div>abc<embed>def</div>", "<div>abc<embed>def<br></div>"]
 FAIL Inserting text when selection is collapsed in <embed> which follows an empty <span> element assert_in_array: The text should be inserted before the previous empty inline element of <embed> value "<div><span></span><embed></div>" not in array ["<div>abc<span></span><embed></div>", "<div>abc<span></span><embed><br></div>"]
@@ -14,6 +16,7 @@
 PASS Inserting text when selection is collapsed in <embed> which follows a non-empty <span> element
 FAIL Inserting text when selection is collapsed in <embed> which follows a text node, an empty <span> element and white-space only text node assert_in_array: The text should be inserted before the previous empty inline element value "<div>abcdef<span></span><embed></div>" not in array ["<div>abcdef<span></span> <embed></div>", "<div>abcdef<span></span> <embed><br></div>"]
 PASS Inserting text when selection is collapsed in <hr> which is only child
+PASS Inserting text when selection is collapsed in <hr> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting text when selection is collapsed in <hr> which follows a text node
 PASS Inserting text when selection is collapsed in <hr> which is followed by a text node
 PASS Inserting text when selection is collapsed in <hr> which follows an empty <span> element
@@ -21,6 +24,7 @@
 PASS Inserting text when selection is collapsed in <hr> which follows a non-empty <span> element
 FAIL Inserting text when selection is collapsed in <hr> which follows a text node, an empty <span> element and white-space only text node assert_in_array: The text should be inserted after the previous empty inline element value "<div>abc<span></span>\ndef<hr></div>" not in array ["<div>abc<span></span>def<hr></div>", "<div>abc<span></span>def<br><hr></div>"]
 PASS Inserting text when selection is collapsed in <img> which is only child
+PASS Inserting text when selection is collapsed in <img> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting text when selection is collapsed in <img> which follows a text node
 PASS Inserting text when selection is collapsed in <img> which is followed by a text node
 PASS Inserting text when selection is collapsed in <img> which follows an empty <span> element
@@ -28,6 +32,7 @@
 PASS Inserting text when selection is collapsed in <img> which follows a non-empty <span> element
 PASS Inserting text when selection is collapsed in <img> which follows a text node, an empty <span> element and white-space only text node
 PASS Inserting text when selection is collapsed in <input> which is only child
+PASS Inserting text when selection is collapsed in <input> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting text when selection is collapsed in <input> which follows a text node
 PASS Inserting text when selection is collapsed in <input> which is followed by a text node
 PASS Inserting text when selection is collapsed in <input> which follows an empty <span> element
@@ -35,6 +40,7 @@
 PASS Inserting text when selection is collapsed in <input> which follows a non-empty <span> element
 PASS Inserting text when selection is collapsed in <input> which follows a text node, an empty <span> element and white-space only text node
 PASS Inserting text when selection is collapsed in <wbr> which is only child
+PASS Inserting text when selection is collapsed in <wbr> which is only child (explicitly flushes maybe pending layout)
 PASS Inserting text when selection is collapsed in <wbr> which follows a text node
 FAIL Inserting text when selection is collapsed in <wbr> which is followed by a text node assert_in_array: The text should be inserted before the <wbr> element value "<div><wbr>abcdef</div>" not in array ["<div>abc<wbr>def</div>", "<div>abc<wbr>def<br></div>"]
 PASS Inserting text when selection is collapsed in <wbr> which follows an empty <span> element
diff --git a/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative.html b/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative.html
index a67f061b..f84d3fc 100644
--- a/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/editing/other/insert-text-in-void-element.tentative.html
@@ -57,6 +57,36 @@
   }, `Inserting text when selection is collapsed in <${tag}> which is only child`);
 
   test(() => {
+    editor.innerHTML = `<div></div>`;
+    const element = document.createElement(tag);
+    editor.firstChild.appendChild(element);
+    editor.focus();
+    const selection = getSelection();
+    selection.collapse(element, 0);
+    element.getBoundingClientRect();
+    document.execCommand("insertText", false, "abc");
+    if (tag == "br") {
+      assert_in_array(
+        editor.innerHTML,
+        [
+          "<div>abc</div>",
+          "<div>abc<br></div>",
+        ],
+        `The text should be inserted before the <br> element`
+      );
+    } else {
+      assert_in_array(
+        editor.innerHTML,
+        [
+          `<div>abc<${tag}></div>`,
+          `<div>abc<${tag}><br></div>`,
+        ],
+        `The text should be inserted before the <${tag}> element`
+      );
+    }
+  }, `Inserting text when selection is collapsed in <${tag}> which is only child (explicitly flushes maybe pending layout)`);
+
+  test(() => {
     editor.innerHTML = `<div>abc</div>`;
     const element = document.createElement(tag);
     editor.firstChild.appendChild(element);
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/delete_6001-7000-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/delete_6001-7000-expected.txt
index 732c8ae..473aea3 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/delete_6001-7000-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/delete_6001-7000-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 1000 tests; 962 PASS, 38 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 1000 tests; 969 PASS, 31 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["defaultparagraphseparator","div"],["delete",""]] "<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz" queryCommandState("delete") before
 PASS [["defaultparagraphseparator","div"],["delete",""]] "<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz" queryCommandValue("delete") before
 PASS [["defaultparagraphseparator","div"],["delete",""]] "<p>foo<ol><li>bar<li>ba[z</ol><p>q]uz" queryCommandIndeterm("delete") after
@@ -681,7 +681,7 @@
 PASS [["defaultparagraphseparator","p"],["delete",""]] "<ul><li>foo</ul><p>{}<br></p><ol><li>bar</ol>" queryCommandValue("delete") after
 PASS [["delete",""]] "<p><b>[foo]</b>": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<p><b>[foo]</b>" checks for modifications to non-editable content
-FAIL [["delete",""]] "<p><b>[foo]</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
+PASS [["delete",""]] "<p><b>[foo]</b>" compare innerHTML
 PASS [["delete",""]] "<p><b>[foo]</b>" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<p><b>[foo]</b>" queryCommandState("delete") before
 PASS [["delete",""]] "<p><b>[foo]</b>" queryCommandValue("delete") before
@@ -690,7 +690,7 @@
 PASS [["delete",""]] "<p><b>[foo]</b>" queryCommandValue("delete") after
 PASS [["delete",""]] "<p><quasit>[foo]</quasit>": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<p><quasit>[foo]</quasit>" checks for modifications to non-editable content
-FAIL [["delete",""]] "<p><quasit>[foo]</quasit>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><quasit><br></quasit></p>" but got "<p><br></p>"
+PASS [["delete",""]] "<p><quasit>[foo]</quasit>" compare innerHTML
 PASS [["delete",""]] "<p><quasit>[foo]</quasit>" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<p><quasit>[foo]</quasit>" queryCommandState("delete") before
 PASS [["delete",""]] "<p><quasit>[foo]</quasit>" queryCommandValue("delete") before
@@ -699,7 +699,7 @@
 PASS [["delete",""]] "<p><quasit>[foo]</quasit>" queryCommandValue("delete") after
 PASS [["delete",""]] "<p><b><i>[foo]</i></b>": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<p><b><i>[foo]</i></b>" checks for modifications to non-editable content
-FAIL [["delete",""]] "<p><b><i>[foo]</i></b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><i><br></i></b></p>" but got "<p><br></p>"
+PASS [["delete",""]] "<p><b><i>[foo]</i></b>" compare innerHTML
 PASS [["delete",""]] "<p><b><i>[foo]</i></b>" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<p><b><i>[foo]</i></b>" queryCommandState("delete") before
 PASS [["delete",""]] "<p><b><i>[foo]</i></b>" queryCommandValue("delete") before
@@ -708,7 +708,7 @@
 PASS [["delete",""]] "<p><b><i>[foo]</i></b>" queryCommandValue("delete") after
 PASS [["delete",""]] "<p><b>{foo}</b>": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<p><b>{foo}</b>" checks for modifications to non-editable content
-FAIL [["delete",""]] "<p><b>{foo}</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
+PASS [["delete",""]] "<p><b>{foo}</b>" compare innerHTML
 PASS [["delete",""]] "<p><b>{foo}</b>" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<p><b>{foo}</b>" queryCommandState("delete") before
 PASS [["delete",""]] "<p><b>{foo}</b>" queryCommandValue("delete") before
@@ -717,7 +717,7 @@
 PASS [["delete",""]] "<p><b>{foo}</b>" queryCommandValue("delete") after
 PASS [["delete",""]] "<p>{<b>foo</b>}": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<p>{<b>foo</b>}" checks for modifications to non-editable content
-FAIL [["delete",""]] "<p>{<b>foo</b>}" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
+PASS [["delete",""]] "<p>{<b>foo</b>}" compare innerHTML
 PASS [["delete",""]] "<p>{<b>foo</b>}" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<p>{<b>foo</b>}" queryCommandState("delete") before
 PASS [["delete",""]] "<p>{<b>foo</b>}" queryCommandValue("delete") before
@@ -726,7 +726,7 @@
 PASS [["delete",""]] "<p>{<b>foo</b>}" queryCommandValue("delete") after
 PASS [["delete",""]] "<p><b>f[]</b>": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<p><b>f[]</b>" checks for modifications to non-editable content
-FAIL [["delete",""]] "<p><b>f[]</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<p><b><br></b></p>" but got "<p><br></p>"
+PASS [["delete",""]] "<p><b>f[]</b>" compare innerHTML
 PASS [["delete",""]] "<p><b>f[]</b>" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<p><b>f[]</b>" queryCommandState("delete") before
 PASS [["delete",""]] "<p><b>f[]</b>" queryCommandValue("delete") before
@@ -735,7 +735,7 @@
 PASS [["delete",""]] "<p><b>f[]</b>" queryCommandValue("delete") after
 PASS [["delete",""]] "<b>[foo]</b>": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<b>[foo]</b>" checks for modifications to non-editable content
-FAIL [["delete",""]] "<b>[foo]</b>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<b><br></b>" but got "<br>"
+PASS [["delete",""]] "<b>[foo]</b>" compare innerHTML
 PASS [["delete",""]] "<b>[foo]</b>" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<b>[foo]</b>" queryCommandState("delete") before
 PASS [["delete",""]] "<b>[foo]</b>" queryCommandValue("delete") before
@@ -744,7 +744,7 @@
 PASS [["delete",""]] "<b>[foo]</b>" queryCommandValue("delete") after
 PASS [["delete",""]] "<div><b>[foo]</b></div>": execCommand("delete", false, "") return value
 PASS [["delete",""]] "<div><b>[foo]</b></div>" checks for modifications to non-editable content
-FAIL [["delete",""]] "<div><b>[foo]</b></div>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div><b><br></b></div>" but got "<br>"
+FAIL [["delete",""]] "<div><b>[foo]</b></div>" compare innerHTML assert_equals: Unexpected innerHTML (after normalizing inline style) expected "<div><br></div>" but got "<br>"
 PASS [["delete",""]] "<div><b>[foo]</b></div>" queryCommandIndeterm("delete") before
 PASS [["delete",""]] "<div><b>[foo]</b></div>" queryCommandState("delete") before
 PASS [["delete",""]] "<div><b>[foo]</b></div>" queryCommandValue("delete") before
diff --git a/third_party/blink/web_tests/external/wpt/editing/run/multitest_9001-last-expected.txt b/third_party/blink/web_tests/external/wpt/editing/run/multitest_9001-last-expected.txt
index 885c30d..26d9c15 100644
--- a/third_party/blink/web_tests/external/wpt/editing/run/multitest_9001-last-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/editing/run/multitest_9001-last-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 214 tests; 202 PASS, 12 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 282 tests; 255 PASS, 27 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS [["delete",""],["inserttext","a"]] "foo<font color=#0000FF>[bar</font>baz]" queryCommandIndeterm("inserttext") before
 PASS [["delete",""],["inserttext","a"]] "foo<font color=#0000FF>[bar</font>baz]" queryCommandState("inserttext") before
 PASS [["delete",""],["inserttext","a"]] "foo<font color=#0000FF>[bar</font>baz]" queryCommandValue("inserttext") before
@@ -214,5 +214,73 @@
 PASS [["delete",""],["inserttext","a"]] "<blockquote><font color=blue>[foo]</font></blockquote>" queryCommandIndeterm("inserttext") after
 PASS [["delete",""],["inserttext","a"]] "<blockquote><font color=blue>[foo]</font></blockquote>" queryCommandState("inserttext") after
 PASS [["delete",""],["inserttext","a"]] "<blockquote><font color=blue>[foo]</font></blockquote>" queryCommandValue("inserttext") after
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("styleWithCSS", false, "false") return value
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("delete", false, "") return value
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("inserttext", false, "a") return value
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" checks for modifications to non-editable content
+FAIL [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" compare innerHTML assert_in_array: Unexpected innerHTML (after normalizing inline style) value "<b>a</b>" not in array ["<div><b>a</b></div>", "<div><b>a</b><br></div>"]
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandIndeterm("bold") before
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandState("bold") before
+FAIL [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandValue("bold") before assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandIndeterm("bold") after
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandState("bold") after
+FAIL [["styleWithCSS","false"],["delete",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandValue("bold") after assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("styleWithCSS", false, "false") return value
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("delete", false, "") return value
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("inserttext", false, "d") return value
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" checks for modifications to non-editable content
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" compare innerHTML
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandIndeterm("bold") before
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandState("bold") before
+FAIL [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandValue("bold") before assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandIndeterm("bold") after
+PASS [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandState("bold") after
+FAIL [["styleWithCSS","false"],["delete",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandValue("bold") after assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("styleWithCSS", false, "false") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("delete", false, "") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("insertparagraph", false, "") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("inserttext", false, "a") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" checks for modifications to non-editable content
+FAIL [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" compare innerHTML assert_in_array: Unexpected innerHTML (after normalizing inline style) value "<br><div><b>a</b></div>" not in array ["<div><br></div><div><b>a</b></div>", "<div><br></div><div><b>a</b><br></div>"]
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandIndeterm("bold") before
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandState("bold") before
+FAIL [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandValue("bold") before assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandIndeterm("bold") after
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandState("bold") after
+FAIL [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandValue("bold") after assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("styleWithCSS", false, "false") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("delete", false, "") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("insertparagraph", false, "") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("inserttext", false, "d") return value
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" checks for modifications to non-editable content
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" compare innerHTML
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandIndeterm("bold") before
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandState("bold") before
+FAIL [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandValue("bold") before assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandIndeterm("bold") after
+PASS [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandState("bold") after
+FAIL [["styleWithCSS","false"],["delete",""],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandValue("bold") after assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("styleWithCSS", false, "false") return value
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("insertparagraph", false, "") return value
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>": execCommand("inserttext", false, "a") return value
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" checks for modifications to non-editable content
+FAIL [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" compare innerHTML assert_in_array: Unexpected innerHTML (after normalizing inline style) value "<br><div><b>a</b></div>" not in array ["<div><br></div><div><b>a</b></div>", "<div><br></div><div><b>a</b><br></div>"]
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandIndeterm("bold") before
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandState("bold") before
+FAIL [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandValue("bold") before assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandIndeterm("bold") after
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandState("bold") after
+FAIL [["styleWithCSS","false"],["insertparagraph",""],["inserttext","a"]] "<div><b>[abc]</b></div>" queryCommandValue("bold") after assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("styleWithCSS", false, "false") return value
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("insertparagraph", false, "") return value
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>": execCommand("inserttext", false, "d") return value
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" checks for modifications to non-editable content
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" compare innerHTML
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandIndeterm("bold") before
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandState("bold") before
+FAIL [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandValue("bold") before assert_equals: Wrong result returned expected "" but got "true"
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandIndeterm("bold") after
+PASS [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandState("bold") after
+FAIL [["styleWithCSS","false"],["insertparagraph",""],["inserttext","d"]] "<div>abc<b>[def]</b></div>" queryCommandValue("bold") after assert_equals: Wrong result returned expected "" but got "true"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html
new file mode 100644
index 0000000..f5eaddbd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<html>
+<title> Images on a page Cross-Origin-Embedder-Policy: require-corp should load the same from the cache or network</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script>
+
+function remote(path) {
+  const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
+  return new URL(path, REMOTE_ORIGIN);
+}
+
+//
+// This test loads a same-orign iframe resources/load_corp_images.html with
+// Cross-Origin-Embedder-Policy: require-corp
+// The iframe loads two cross origin images, one with a
+// Cross-Origin-Resource-Policy: cross-origin header, and one without.
+// We expect the image with the header to load successfully and the one without
+// to fail to load.
+// After the first load we then reload the iframe, with the same expectations
+// for the image loads when they are loaded from the cache.
+//
+
+const image_path = "/html/cross-origin-embedder-policy/resources/corp-image.py";
+
+let EXPECTED_LOADS = {
+  [`NETWORK-${remote(image_path)}`]: false,
+  [`NETWORK-${remote(image_path)}?corp-cross-origin=1`]: true,
+  [`CACHED-${remote(image_path)}`]: false,
+  [`CACHED-${remote(image_path)}?corp-cross-origin=1`]: true,
+}
+
+let TESTS = {};
+for (let t in EXPECTED_LOADS) {
+  TESTS[t] = async_test(t);
+}
+
+window.addEventListener("load", async () => {
+  let iframe = document.createElement("iframe");
+  let firstRun = true;
+  let t = async_test("main_test");
+  await new Promise((resolve, reject) => {
+    iframe.src = "resources/load-corp-images.html";
+    iframe.onload = () => { resolve() };
+    iframe.onerror = (e) => { reject(); };
+    window.addEventListener("message", (event) => {
+      // After the first done event we reload the iframe.
+      if (event.data.done) {
+        if (firstRun) {
+          firstRun = false;
+          iframe.contentWindow.location.reload();
+        } else {
+          // After the second done event the test is finished.
+          t.done();
+        }
+      } else {
+        // Check that each image either loads or doesn't based on the expectations
+        let testName = `${firstRun ? "NETWORK-" : "CACHED-"}${event.data.src}`;
+        let test = TESTS[testName];
+        test.step(() => {
+          assert_equals(event.data.loaded, EXPECTED_LOADS[testName], `${firstRun ? "NETWORK" : "CACHED"} load of ${event.data.src} should ${EXPECTED_LOADS[testName] ? "" : "not"} succeed`);
+        });
+        test.done();
+      }
+    }, false);
+    document.body.appendChild(iframe);
+  })
+});
+
+
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html.headers
new file mode 100644
index 0000000..66044509
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/require-corp-cached-images.https.html.headers
@@ -0,0 +1 @@
+Cross-Origin-Embedder-Policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/corp-image.py b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/corp-image.py
new file mode 100644
index 0000000..29689c4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/corp-image.py
@@ -0,0 +1,27 @@
+import json
+import base64
+
+# A 1x1 PNG image.
+# Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
+IMAGE = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAAACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII="
+
+def main(request, response):
+    response.headers.set(b'Access-Control-Allow-Origin', b'*')
+    response.headers.set(b'Access-Control-Allow-Methods', b'OPTIONS, GET, POST')
+    response.headers.set(b'Access-Control-Allow-Headers', b'Content-Type')
+
+    response.headers.set(b"Cache-Control", b"max-age=3600");
+    # CORS preflight
+    if request.method == u'OPTIONS':
+        return u''
+
+    if b'some-etag' == request.headers.get(b"If-None-Match", None):
+        response.status = 304
+        return u''
+
+    if request.GET.first(b"corp-cross-origin", default=b""):
+        response.headers.set(b'Cross-Origin-Resource-Policy', b'cross-origin')
+
+    response.headers.set(b'Etag', b'some-etag')
+    response.headers.set(b'Content-Type', b'image/png')
+    return base64.b64decode(IMAGE)
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html
new file mode 100644
index 0000000..1251b8c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+<script src="/common/get-host-info.sub.js"></script>
+<script>
+
+function remote(path) {
+  const REMOTE_ORIGIN = get_host_info().HTTPS_REMOTE_ORIGIN;
+  return new URL(path, REMOTE_ORIGIN);
+}
+
+const image_path = "/html/cross-origin-embedder-policy/resources/corp-image.py";
+
+window.addEventListener("load", async () => {
+  await new Promise(resolve => {
+    let img = document.createElement("img");
+    img.src = remote(image_path);
+    img.onload = () => { window.parent.postMessage({loaded: true, src: img.src}, "*"); resolve(); };
+    img.onerror = (e) => { window.parent.postMessage({loaded: false, src: img.src}, "*"); resolve(); };
+    document.body.appendChild(img);
+  });
+
+  await new Promise(resolve => {
+    let img = document.createElement("img");
+    img.src = remote(image_path + "?corp-cross-origin=1");
+    img.onload = () => { window.parent.postMessage({loaded: true, src: img.src}, "*"); resolve(); };
+    img.onerror = (e) => { window.parent.postMessage({loaded: false, src: img.src}, "*"); resolve(); };
+    document.body.appendChild(img);
+  });
+
+  window.parent.postMessage({done: true}, "*")
+});
+
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html.headers b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html.headers
new file mode 100644
index 0000000..8df9847
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/cross-origin-embedder-policy/resources/load-corp-images.html.headers
@@ -0,0 +1 @@
+cross-origin-embedder-policy: require-corp
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-below-viewport-dynamic.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-below-viewport-dynamic.html
index 7fc2c742..78f18f0c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-below-viewport-dynamic.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-below-viewport-dynamic.html
@@ -34,7 +34,7 @@
 
 <body>
   <div style="height:10000px;"></div>
-  <img id="below_viewport" src="resources/image.png?pipe=trickle(d2)"
+  <img id="below_viewport" src="resources/image.png?below-viewport-dynamic&pipe=trickle(d2)"
        loading="lazy" onload="below_viewport_img_onload();">
   <script>
     assert_false(has_window_loaded,
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-viewport-dynamic.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-viewport-dynamic.html
index 982f09b..39dd5dc 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-viewport-dynamic.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-in-viewport-dynamic.html
@@ -32,7 +32,7 @@
 </script>
 
 <body>
-  <img id="in_viewport" src="resources/image.png?pipe=trickle(d2)"
+  <img id="in_viewport" src="resources/image.png?in-viewport-dynamic&pipe=trickle(d2)"
        loading="lazy" onload="in_viewport_img_onload();">
   <script>
     document.getElementById("in_viewport").loading = 'eager';
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-negative-margin.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-negative-margin.html
index 43a2c46..1651d8d 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-negative-margin.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-negative-margin.html
@@ -25,7 +25,7 @@
 
   <div style="width: 200px; height: 200px; overflow: hidden;">
     <img id="negative_margin" width="5px"; style="margin-left: -10px;"
-         loading="lazy" src="resources/image.png"
+         loading="lazy" src="resources/image.png?loading-lazy-negative-margin"
          onload="window.negative_margin_onload()">
   </div>
 
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-relevant-mutations.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-relevant-mutations.html
index cd4b99dd..3a26624 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-relevant-mutations.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-relevant-mutations.html
@@ -61,7 +61,7 @@
       below_viewport_3.onerror = reject;
       t.step_timeout(resolve, 1000);
 
-      below_viewport_3.src = "resources/image.png?change";
+      below_viewport_3.src = "resources/image.png?relevant-mutations-change";
     });
   }, "Image src mutation does not cause deferred loading=lazy " +
      "images to be fetched");
@@ -69,15 +69,15 @@
 
 <body>
   <div style="height:1000vh;"></div>
-  <img id="below-viewport-1" src="resources/image.png?1" loading="lazy"
+  <img id="below-viewport-1" src="resources/image.png?relevant-mutations-1" loading="lazy"
        onload="below_viewport_1_loaded = true"
        onerror="below_viewport_1_loaded = true">
 
-  <img id="below-viewport-2" src="resources/image.png?2" loading="lazy"
+  <img id="below-viewport-2" src="resources/image.png?relevant-mutations-2" loading="lazy"
        onload="below_viewport_2_loaded = true"
        onerror="below_viewport_2_loaded = true">
 
-  <img id="below-viewport-3" src="resources/image.png?3" loading="lazy"
+  <img id="below-viewport-3" src="resources/image.png?relevant-mutations-3" loading="lazy"
        onload="below_viewport_3_loaded = true"
        onerror="below_viewport_3_loaded = true">
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio.html
index 2d302970..662ada6 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow-aspect-ratio.html
@@ -13,9 +13,9 @@
     loaded = true;
     target.src = "";
     requestAnimationFrame(() => requestAnimationFrame(() => {
-      target.src = "resources/image.png?pipe=trickle(d2)";
+      target.src = "resources/image.png?slow-aspect-ratio&pipe=trickle(d2)";
       takeScreenshot();
     }));
   };
-  target.src = "resources/image.png";
+  target.src = "resources/image.png?slow-aspect-ratio";
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow.html
index a972100..fac2c2e 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-slow.html
@@ -14,9 +14,9 @@
     loaded = true;
     target.src = "";
     requestAnimationFrame(() => requestAnimationFrame(() => {
-      target.src = "resources/image.png?pipe=trickle(d2)";
+      target.src = "resources/image.png?loading-lazy-slow&pipe=trickle(d2)";
       takeScreenshot();
     }));
   };
-  target.src = "resources/image.png";
+  target.src = "resources/image.png?loading-lazy-slow";
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-to-eager.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-to-eager.html
index f74cafb..62460639 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-to-eager.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/image-loading-lazy-to-eager.html
@@ -47,9 +47,9 @@
 <body>
   <div style="height:1000vh;"></div>
   <img id="img_1"
-       src="resources/image.png?1"
+       src="resources/image.png?lazy-to-eager-1"
        loading="lazy" onload="img_1_onload();">
   <img id="img_2"
-       src="resources/image.png?2"
+       src="resources/image.png?lazy-to-eager-2"
        loading="lazy" onload="img_2_onload();">
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/resources/image-loading-lazy-below-viewport.html b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/resources/image-loading-lazy-below-viewport.html
index 486aeb0..f25bd6f 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/resources/image-loading-lazy-below-viewport.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/embedded-content/the-img-element/resources/image-loading-lazy-below-viewport.html
@@ -1,7 +1,7 @@
 <!DOCTYPE html>
 <div style="height:1000vh;"></div>
 
-<img id="img" loading="lazy" src="image.png">
+<img id="img" loading="lazy" src="image.png?lazy-below-viewport">
 
 <script>
   const img = document.querySelector('#img');
diff --git a/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html
index d4ff60f3..727259b 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html
@@ -10,7 +10,7 @@
   <script>
     const base_url = `${location.protocol}//${location.host}`;
     const endpoint = `${base_url}/reporting/resources/report.py`;
-    const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';
+      const id = 'fe5ca189-269a-4e74-a4dd-d7a3b33139d5';
 
     promise_test(async t => {
       // Set credentials, and set up test to clear them afterwards.
diff --git a/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html.sub.headers
index 007c097..24eaf19f 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html.sub.headers
+++ b/third_party/blink/web_tests/external/wpt/reporting/cross-origin-report-no-credentials.https.sub.html.sub.headers
@@ -1,2 +1,2 @@
-Reporting-Endpoints: csp-endpoint="https://{{domains[www1]}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf"
+Reporting-Endpoints: csp-endpoint="https://{{domains[www1]}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=fe5ca189-269a-4e74-a4dd-d7a3b33139d5"
 Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-endpoint
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-bypass-report-to.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-bypass-report-to.https.sub.html
new file mode 100644
index 0000000..394bc9e4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-bypass-report-to.https.sub.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+  <title>Test that reports ignore Report-To header when Reporting-Endpoints is configured</title>
+  <script src='/resources/testharness.js'></script>
+  <script src='/resources/testharnessreport.js'></script>
+  <script src='resources/report-helper.js'></script>
+</head>
+
+<body>
+  <script>
+    promise_test(async t => {
+      return new Promise(resolve => {
+        new ReportingObserver((reports, observer) => resolve(reports),
+          { types: ['document-policy-violation'] }).observe();
+      }).then((reports) => {
+        assert_equals(reports[0].type, 'document-policy-violation');
+      })
+    }, "document policy violation observed");
+  </script>
+  <script>document.write("This should be written into the document");</script>
+  <script>
+    const base_url = `${location.protocol}//${location.host}`;
+    const endpoint = `${base_url}/reporting/resources/report.py`;
+      const report_to_id = 'caddb022-90ea-48e8-a675-4cebaf7e8388';
+    const reporting_endpoints_id = '6c2131d0-1e9b-4ee8-a196-952f2ae4ae97';
+    promise_test(async t => {
+      await wait(3000);
+      // Verify no reports sent to Report-To endpoint
+      let reports = await pollReports(endpoint, report_to_id);
+      assert_equals(reports.length, 0);
+      // Verify report is received on Reporting-Endpoints endpoint
+      reports = await pollReports(endpoint, reporting_endpoints_id);
+      checkReportExists(reports, 'document-policy-violation', location.href);
+    }, "Only the Reporting-Endpoints configured endpoint received reports.");
+  </script>
+
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-bypass-report-to.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-bypass-report-to.https.sub.html.sub.headers
new file mode 100644
index 0000000..b2a3d20f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-bypass-report-to.https.sub.html.sub.headers
@@ -0,0 +1,3 @@
+Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=6c2131d0-1e9b-4ee8-a196-952f2ae4ae97"
+Report-To: { "group": "group1", "max_age": 10886400, "endpoints": [{ "url": "/reporting/resources/report.py?reportID=caddb022-90ea-48e8-a675-4cebaf7e8388" }] }
+Document-Policy-Report-Only: document-write=?0;report-to=group1
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-default-endpoint.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-default-endpoint.https.sub.html
new file mode 100644
index 0000000..24c1216a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-default-endpoint.https.sub.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Test that document level reports are sent to default endpoint</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src='resources/report-helper.js'></script>
+<p id="error">No error</p>
+<script>
+  async_test(function (test) {
+    var observer = new ReportingObserver(function (reports) {
+      test.step(function () {
+        assert_equals(reports.length, 1);
+        assert_equals(reports[0].type, "deprecation");
+      });
+      test.done();
+    });
+    observer.observe();
+  }, "report generated");
+</script>
+<script>window.webkitStorageInfo;</script>
+<script>
+  const base_url = `${location.protocol}//${location.host}`;
+  const endpoint = `${base_url}/reporting/resources/report.py`;
+    const id = '46ecac28-6d27-4763-a692-bcc588054716';
+  promise_test(async t => {
+    await wait(3000);
+    const reports = await pollReports(endpoint, id);
+    checkReportExists(reports, 'deprecation', location.href);
+  }, "Reporting-Endpoints defined endpoint received reports.");
+</script>
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-default-endpoint.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-default-endpoint.https.sub.html.sub.headers
new file mode 100644
index 0000000..e374d79
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-default-endpoint.https.sub.html.sub.headers
@@ -0,0 +1 @@
+Reporting-Endpoints: default="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=46ecac28-6d27-4763-a692-bcc588054716"
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-destroy-after-document-close.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-destroy-after-document-close.https.sub.html
new file mode 100644
index 0000000..49ad1fab
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-destroy-after-document-close.https.sub.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+  <title>Test that reports are not sent without Reporting-Endpoints header, with previous header set on same URL</title>
+  <script src="/common/utils.js"></script>
+  <script src='/resources/testharness.js'></script>
+  <script src='/resources/testharnessreport.js'></script>
+  <script src='resources/report-helper.js'></script>
+</head>
+
+<body>
+  <iframe name="test"></iframe>
+  <script>
+    const base_url = `${location.protocol}//${location.host}`;
+    const endpoint = `${base_url}/reporting/resources/report.py`;
+    const report_id = token();
+    const document_url =
+      `resources/generate-report-once.py?reportID=${report_id}`;
+    promise_test(async t => {
+      // Load a document that generates report into iframe. Server should return
+      // Reporting-Endpoints header.
+      const w = window.open(document_url, "test");
+      await wait(1000);
+      let reports = await pollReports(endpoint, report_id);
+      // Verify that reporting is configured on the document.
+      assert_equals(reports.length, 1);
+      // reload opened window. This time server will not return
+      // Reporting-Endpoints header.
+      w.location.reload();
+      await wait(1000);
+      reports = await pollReports(endpoint, report_id);
+      // Verify no reports are sent this time.
+      assert_equals(reports.length, 0);
+
+    }, "No more reports received after navigation to same document without endpoint header");
+  </script>
+
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-named-endpoints.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-named-endpoints.https.sub.html
new file mode 100644
index 0000000..c246011
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-named-endpoints.https.sub.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+  <title>Test that reports are sent to multiple named endpoints</title>
+  <script src='/resources/testharness.js'></script>
+  <script src='/resources/testharnessreport.js'></script>
+  <script src='resources/report-helper.js'></script>
+</head>
+
+<body>
+  <script>
+    const t = async_test("Test that image does not load");
+    async_test(function (t) {
+      const observer = new ReportingObserver((reports, observer) => {
+        t.step(() => {
+          assert_equals(reports[0].type, 'csp-violation');
+        });
+        t.done();
+      }, { types: ['csp-violation'] });
+      observer.observe();
+    }, "csp violation report observed");
+
+    promise_test(async t => {
+      return new Promise(resolve => {
+        new ReportingObserver((reports, observer) => resolve(reports),
+          { types: ['document-policy-violation'] }).observe();
+      }).then((reports) => {
+        assert_equals(reports[0].type, 'document-policy-violation');
+      })
+    }, "document policy violation observed");
+  </script>
+  <img src='/reporting/resources/fail.png' onload='t.unreached_func("The image should not have loaded");'
+    onerror='t.done();'>
+  <script>document.write("This should be written into the document");</script>
+  <script>
+    const base_url = `${location.protocol}//${location.host}`;
+    const endpoint = `${base_url}/reporting/resources/report.py`;
+    const group1_id = '0d334af1-1c5c-4e59-9079-065131ff2a45';
+    const group2_id = '09c1a265-5fc7-4c49-b35c-32078c2d0c19';
+    promise_test(async t => {
+      await wait(3000);
+      // Verify CSP reports are sent to configured endpoint.
+      const csp_reports = await pollReports(endpoint, group1_id);
+      checkReportExists(csp_reports, 'csp-violation', location.href);
+      // Verify Document Policy reports are sent to configured endpoint.
+      const dp_reports = await pollReports(endpoint, group2_id);
+      checkReportExists(dp_reports, 'document-policy-violation', location.href);
+    }, "Reporting endpoints received reports.");
+  </script>
+
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-named-endpoints.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-named-endpoints.https.sub.html.sub.headers
new file mode 100644
index 0000000..2d5a308
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-named-endpoints.https.sub.html.sub.headers
@@ -0,0 +1,4 @@
+Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=0d334af1-1c5c-4e59-9079-065131ff2a45"
+Reporting-Endpoints: group2="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=09c1a265-5fc7-4c49-b35c-32078c2d0c19"
+Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to group1
+Document-Policy-Report-Only: document-write=?0;report-to=group2
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-not-batch-different-document.https.html b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-not-batch-different-document.https.html
new file mode 100644
index 0000000..e124bd7f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-not-batch-different-document.https.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+  <title>Test that reports are sent to multiple named endpoints</title>
+  <script src='/resources/testharness.js'></script>
+  <script src='/resources/testharnessreport.js'></script>
+  <script src='resources/report-helper.js'></script>
+</head>
+
+<body>
+  <iframe name="report1"></iframe>
+  <iframe name="report2"></iframe>
+  <script>
+    const base_url = `${location.protocol}//${location.host}`;
+    const endpoint = `${base_url}/reporting/resources/report.py`;
+    const report_id = '204d2fb2-018b-4e35-964c-5e298e89d4e2';
+    promise_test(async t => {
+      const w = window.open(`resources/generate-report.https.sub.html?pipe=header(Reporting-Endpoints,default="/reporting/resources/report.py?reportID=${report_id}")`, "report1");
+      const w2 = window.open(`resources/generate-csp-report.https.sub.html?pipe=header(Reporting-Endpoints,default="/reporting/resources/report.py?reportID=${report_id}")`, "report2");
+      await wait(3000);
+      // Verify that each iframe generated and sent one report.
+      const reports = await pollReports(endpoint, report_id);
+      assert_equals(reports.length, 2, "Number of reports");
+      checkReportExists(reports, 'deprecation', w.location.href);
+      checkReportExists(reports, 'csp-violation', w2.location.href);
+      const request_count = await pollNumResults(endpoint, report_id);
+      // Verify that requests are sent separately.
+      assert_equals(request_count, 2, "Count of requests");
+    }, "Reports are not batched for same url in different document.");
+  </script>
+
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-override-endpoint.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-override-endpoint.https.sub.html
new file mode 100644
index 0000000..9264786
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-override-endpoint.https.sub.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+  <title>Test that Reporting-Endpoints header endpoint with same name override previous value</title>
+  <script src='/resources/testharness.js'></script>
+  <script src='/resources/testharnessreport.js'></script>
+  <script src='resources/report-helper.js'></script>
+</head>
+
+<body>
+  <script>
+    promise_test(async t => {
+      return new Promise(resolve => {
+        new ReportingObserver((reports, observer) => resolve(reports),
+          { types: ['document-policy-violation'] }).observe();
+      }).then((reports) => {
+        assert_equals(reports[0].type, 'document-policy-violation');
+      })
+    }, "document policy violation observed");
+  </script>
+  <script>document.write("This should be written into the document");</script>
+  <script>
+    const base_url = `${location.protocol}//${location.host}`;
+    const endpoint = `${base_url}/reporting/resources/report.py`;
+    const first_group1_id = 'b523d7f5-28f0-4be6-9460-e163ee9b4ab8';
+    const second_group1_id = '03e4474d-768c-42f2-8e17-39aa95b309e3';
+    promise_test(async t => {
+      await wait(3000);
+      // Verify that no reports are sent to old header endpoint.
+      let reports = await pollReports(endpoint, first_group1_id);
+      assert_equals(reports.length, 0);
+      // Verify that reports are sent to the new header endpoint.
+      reports = await pollReports(endpoint, second_group1_id);
+      checkReportExists(reports, 'document-policy-violation', location.href);
+    }, "Only the second reporting endpoint received reports.");
+  </script>
+
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-override-endpoint.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-override-endpoint.https.sub.html.sub.headers
new file mode 100644
index 0000000..46954f4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-override-endpoint.https.sub.html.sub.headers
@@ -0,0 +1,3 @@
+Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=b523d7f5-28f0-4be6-9460-e163ee9b4ab8"
+Reporting-Endpoints: group1="https://{{host}}:{{ports[https][0]}}/reporting/resources/report.py?reportID=03e4474d-768c-42f2-8e17-39aa95b309e3"
+Document-Policy-Report-Only: document-write=?0;report-to=group1
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-path-absolute.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-path-absolute.https.sub.html
new file mode 100644
index 0000000..e23dd85
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-path-absolute.https.sub.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Test that Reporting-Endpoints report received for absolute path endpoint.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src='resources/report-helper.js'></script>
+<p id="error">No error</p>
+<script>
+  async_test(function (test) {
+    var observer = new ReportingObserver(function (reports) {
+      test.step(function () {
+        // Reports should be received in the same order that they were
+        // generated.
+        assert_equals(reports.length, 1);
+        assert_equals(reports[0].type, "deprecation");
+      });
+      test.done();
+    });
+    observer.observe();
+  }, "report generated");
+</script>
+<script>window.webkitStorageInfo;</script>
+<script>
+  const base_url = `${location.protocol}//${location.host}`;
+  const endpoint = `${base_url}/reporting/resources/report.py`;
+  const id = '8106c1d6-55f7-4c82-a8e1-fabc59f890f8';
+  promise_test(async t => {
+    await wait(3000);
+    const reports = await pollReports(endpoint, id);
+    checkReportExists(reports, 'deprecation', location.href);
+  }, "Reporting-Endpoints defined endpoint received reports.");
+</script>
+</body>
+
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/document-reporting-path-absolute.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-path-absolute.https.sub.html.sub.headers
new file mode 100644
index 0000000..547cd6a5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/document-reporting-path-absolute.https.sub.html.sub.headers
@@ -0,0 +1 @@
+Reporting-Endpoints: default="/reporting/resources/report.py?reportID=8106c1d6-55f7-4c82-a8e1-fabc59f890f8"
diff --git a/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html
index ecd44c35..fe119ac5 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html
@@ -53,7 +53,7 @@
   <script>
     promise_test(async t => {
       const endpoint = `${base_url}/reporting/resources/report.py`;
-      const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';
+      const id = '33444bb6-e444-4978-9d62-d3825844041f';
       await wait(3000);
       const reports = await pollReports(endpoint, id);
       checkReportExists(reports, 'csp-violation', location.href);
diff --git a/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html.sub.headers
index 5bd5ae7..64d08940 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html.sub.headers
+++ b/third_party/blink/web_tests/external/wpt/reporting/path-absolute-endpoint.https.sub.html.sub.headers
@@ -1,2 +1,2 @@
-Report-To: { "group": "csp-group", "max_age": 10886400, "endpoints": [{ "url": "/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf" }] }
+Report-To: { "group": "csp-group", "max_age": 10886400, "endpoints": [{ "url": "/reporting/resources/report.py?reportID=33444bb6-e444-4978-9d62-d3825844041f" }] }
 Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-group
diff --git a/third_party/blink/web_tests/external/wpt/reporting/resources/generate-csp-report.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-csp-report.https.sub.html
new file mode 100644
index 0000000..7adec0f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-csp-report.https.sub.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>Generate CSP reports </title>
+<img src='/reporting/resources/fail.png'>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/resources/generate-csp-report.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-csp-report.https.sub.html.sub.headers
new file mode 100644
index 0000000..44242c3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-csp-report.https.sub.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to default
diff --git a/third_party/blink/web_tests/external/wpt/reporting/resources/generate-report-once.py b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-report-once.py
new file mode 100644
index 0000000..076d500
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-report-once.py
@@ -0,0 +1,34 @@
+def main(request, response):
+  # Handle CORS preflight requests
+  if request.method == u'OPTIONS':
+    # Always reject preflights for one subdomain
+    if b"www2" in request.headers[b"Origin"]:
+      return (400, [], u"CORS preflight rejected for www2")
+    return [
+        (b"Content-Type", b"text/plain"),
+        (b"Access-Control-Allow-Origin", b"*"),
+        (b"Access-Control-Allow-Methods", b"get"),
+        (b"Access-Control-Allow-Headers", b"Content-Type"),
+    ], u"CORS allowed"
+
+  if b"reportID" in request.GET:
+    key = request.GET.first(b"reportID")
+  else:
+    response.status = 400
+    return "reportID parameter is required."
+
+  with request.server.stash.lock:
+    visited = request.server.stash.take(key=key)
+    if visited is None:
+      response.headers.set("Reporting-Endpoints",
+                           b"default=\"/reporting/resources/report.py?reportID=%s\"" % key)
+    request.server.stash.put(key=key, value=True)
+
+  response.content = b"""
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Generate deprecation report</title>
+<script>
+  window.webkitStorageInfo;
+</script>
+"""
diff --git a/third_party/blink/web_tests/external/wpt/reporting/resources/generate-report.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-report.https.sub.html
new file mode 100644
index 0000000..ee40c46e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/reporting/resources/generate-report.https.sub.html
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Generate deprecation report</title>
+<script>
+  window.webkitStorageInfo;
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/reporting/resources/report-helper.js b/third_party/blink/web_tests/external/wpt/reporting/resources/report-helper.js
index cc4f07f0..213a635 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/resources/report-helper.js
+++ b/third_party/blink/web_tests/external/wpt/reporting/resources/report-helper.js
@@ -3,7 +3,7 @@
 }
 
 async function pollReports(endpoint, id, min_count) {
-  const res = await fetch(`${endpoint}?reportID=${id}${min_count ? `&min_count=${min_count}` : ''}`, {cache: 'no-store'});
+  const res = await fetch(`${endpoint}?reportID=${id}${min_count ? `&min_count=${min_count}` : ''}`, { cache: 'no-store' });
   const reports = [];
   if (res.status === 200) {
     for (const report of await res.json()) {
@@ -14,7 +14,7 @@
 }
 
 async function pollCookies(endpoint, id) {
-  const res = await fetch(`${endpoint}?reportID=${id}&op=retrieve_cookies`, {cache: 'no-store'});
+  const res = await fetch(`${endpoint}?reportID=${id}&op=retrieve_cookies`, { cache: 'no-store' });
   const dict = await res.json();
   if (dict.reportCookies == 'None')
     return {};
@@ -22,11 +22,11 @@
 }
 
 async function pollNumResults(endpoint, id) {
-  const res = await fetch(`${endpoint}?reportID=${id}&op=retrieve_count`, {cache: 'no-store'});
+  const res = await fetch(`${endpoint}?reportID=${id}&op=retrieve_count`, { cache: 'no-store' });
   const dict = await res.json();
   if (dict.report_count == 'None')
     return 0;
-  return JSON.parse(dict.report_count);
+  return dict.report_count;
 }
 
 function checkReportExists(reports, type, url) {
diff --git a/third_party/blink/web_tests/external/wpt/reporting/resources/report.py b/third_party/blink/web_tests/external/wpt/reporting/resources/report.py
index 441a8a7..b5ee0c07 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/resources/report.py
+++ b/third_party/blink/web_tests/external/wpt/reporting/resources/report.py
@@ -91,7 +91,7 @@
       return [(b"Content-Type", b"application/json")], u"{ \"reportCookies\" : " + str(retrieve_from_stash(request, cookie_key, timeout, u"\"None\"")) + u"}"
 
     if op == b"retrieve_count":
-      return [(b"Content-Type", b"application/json")], json.dumps({u'report_count': str(retrieve_from_stash(request, count_key, timeout, 0))})
+      return [(b"Content-Type", b"application/json")], u"{ \"report_count\": %s }" % retrieve_from_stash(request, count_key, timeout, 0)
 
     response.status = 400
     return "op parameter value not recognized."
diff --git a/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html b/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html
index a7264fa..fb75378 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html
@@ -10,7 +10,7 @@
   <script>
     const base_url = `${location.protocol}//${location.host}`;
     const endpoint = `${base_url}/reporting/resources/report.py`;
-    const id = 'd0d517bf-891b-457a-b970-8b2b2c81a0bf';
+    const id = '320db941-960a-4529-8c4a-24aeb6739309';
 
     promise_test(async t => {
       // Set credentials, and set up test to clear them afterwards.
diff --git a/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html.sub.headers b/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html.sub.headers
index 8244fafb2..a88efd0c 100644
--- a/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html.sub.headers
+++ b/third_party/blink/web_tests/external/wpt/reporting/same-origin-report-credentials.https.sub.html.sub.headers
@@ -1,2 +1,2 @@
-Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID=d0d517bf-891b-457a-b970-8b2b2c81a0bf"
+Reporting-Endpoints: csp-endpoint="/reporting/resources/report.py?reportID=320db941-960a-4529-8c4a-24aeb6739309"
 Content-Security-Policy: script-src 'self' 'unsafe-inline'; img-src 'none'; report-to csp-endpoint
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative-expected.txt
new file mode 100644
index 0000000..116f38c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative-expected.txt
@@ -0,0 +1,102 @@
+This is a testharness.js-based test.
+Found 98 tests; 44 PASS, 54 FAIL, 0 TIMEOUT, 0 NOTRUN.
+PASS Empty block
+PASS EOF ends block
+PASS Timeline name can be a <string>
+PASS Missing prelude
+PASS Missing block
+PASS Missing timeline name
+PASS Timeline name must be an identifier
+PASS Timeline name must match <custom-ident>
+PASS Timeline name must match <custom-ident> (caps)
+PASS Timeline name must match <custom-ident> (mixed)
+PASS Timeline name may not be initial
+PASS Timeline name may not be inherit
+PASS Timeline name may not be unset
+PASS Timeline name may not be revert
+PASS Timeline name may not be default
+PASS Extra timeline name
+PASS CSSRule.type returns 0
+PASS CSSScrollTimelineRule.name foo
+PASS CSSScrollTimelineRule.name Foo
+PASS CSSScrollTimelineRule.name f___123
+PASS CSSScrollTimelineRule.name a\9 b
+PASS CSSScrollTimelineRule.name "foo"
+PASS CSSScrollTimelineRule.name "none"
+PASS CSSScrollTimelineRule.cssText: empty rule
+PASS CSSScrollTimelineRule.cssText: escaped name
+PASS CSSScrollTimelineRule.cssText: source descriptor
+PASS CSSScrollTimelineRule.cssText: orientation descriptor
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (none) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: none; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (auto) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: auto; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (container-based offset, px) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: 100px; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (container-based offset, percentage) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: 100%; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar); }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with edge) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) start; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with threshold) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) 1; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with edge and threshold) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (element offset with threshold and edge) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: scroll-offsets descriptor (multiple offsets) assert_equals: expected "@scroll-timeline timeline { scroll-offsets: auto, selector(#bar) start 1; }" but got "@scroll-timeline timeline { }"
+FAIL CSSScrollTimelineRule.cssText: defaults assert_equals: expected "@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }" but got "@scroll-timeline timeline { source: auto; orientation: auto; }"
+FAIL CSSScrollTimelineRule.cssText: order assert_equals: expected "@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }" but got "@scroll-timeline timeline { source: auto; orientation: auto; }"
+PASS CSSScrollTimelineRule.source selector(#foo)
+PASS CSSScrollTimelineRule.source selector( #foo )
+PASS CSSScrollTimelineRule.source  selector(#foo) 
+PASS CSSScrollTimelineRule.source none
+PASS CSSScrollTimelineRule.source  none 
+PASS CSSScrollTimelineRule.source selector(#a\9 b)
+PASS CSSScrollTimelineRule.source auto
+FAIL CSSScrollTimelineRule.source #foo assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source  assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source element(#foo) assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source selector(#foo more) assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source selector(html) assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source selector(foo) assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source selector(:before) assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source selector(*) assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source selector(.a) assert_equals: serialization should be canonical expected "auto" but got "none"
+FAIL CSSScrollTimelineRule.source selector(.a, .b) assert_equals: serialization should be canonical expected "auto" but got "none"
+PASS CSSScrollTimelineRule.orientation auto
+PASS CSSScrollTimelineRule.orientation block
+PASS CSSScrollTimelineRule.orientation inline
+PASS CSSScrollTimelineRule.orientation horizontal
+PASS CSSScrollTimelineRule.orientation vertical
+PASS CSSScrollTimelineRule.orientation   vertical  
+PASS CSSScrollTimelineRule.orientation 
+PASS CSSScrollTimelineRule.orientation foo
+PASS CSSScrollTimelineRule.orientation 10px
+PASS CSSScrollTimelineRule.orientation red
+FAIL CSSScrollTimelineRule.scrollOffsets none assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets  none  assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets  assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets red assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets #fff assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets unset assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets unknown(#foo) assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets start assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets end assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets 3 assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 start 10 assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets 0%, 100%, selector(.a) assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 end, start assert_equals: serialization should be canonical expected (string) "none" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets auto assert_equals: serialization should be canonical expected (string) "auto" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets 10em assert_equals: serialization should be canonical expected (string) "10em" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets 10% assert_equals: serialization should be canonical expected (string) "10%" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets calc(1px + 1%) assert_in_array: serialization should be sound value undefined not in array ["calc(1px + 1%)", "calc(1% + 1px)"]
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) assert_equals: serialization should be canonical expected (string) "selector(#foo)" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets  selector(#foo) assert_equals: serialization should be canonical expected (string) "selector(#foo)" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) start assert_equals: serialization should be canonical expected (string) "selector(#foo) start" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) start 3 assert_equals: serialization should be canonical expected (string) "selector(#foo) start 3" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 assert_equals: serialization should be canonical expected (string) "selector(#foo) 3" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3.5 assert_equals: serialization should be canonical expected (string) "selector(#foo) 3.5" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) end assert_equals: serialization should be canonical expected (string) "selector(#foo) end" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) end 3 assert_equals: serialization should be canonical expected (string) "selector(#foo) end 3" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) 3 end assert_equals: serialization should be canonical expected (string) "selector(#foo) end 3" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets  auto , auto  assert_equals: serialization should be canonical expected (string) "auto, auto" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets 10%, 100px assert_equals: serialization should be canonical expected (string) "10%, 100px" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets auto, 100% assert_equals: serialization should be canonical expected (string) "auto, 100%" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets 0%, selector(  #foo)  3  end   assert_equals: serialization should be canonical expected (string) "0%, selector(#foo) end 3" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets selector(#foo) end 3, selector(#bar) assert_equals: serialization should be canonical expected (string) "selector(#foo) end 3, selector(#bar)" but got (undefined) undefined
+FAIL CSSScrollTimelineRule.scrollOffsets 0%, auto, selector(#foo) start, auto, selector(#bar) 12.3 assert_equals: serialization should be canonical expected (string) "0%, auto, selector(#foo) start, auto, selector(#bar) 12.3" but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html
index afca950..8724ddd 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/scroll-timeline-cssom.tentative.html
@@ -48,7 +48,11 @@
   test_stylesheet(`@scroll-timeline test { ${descriptor}:${specified}; }`, (rules) => {
     assert_equals(rules.length, 1);
     assert_equals(rules[0].constructor.name, 'CSSScrollTimelineRule');
-    assert_equals(rules[0][attribute], expected);
+    if (Array.isArray(expected)) {
+      assert_in_array(rules[0][attribute], expected, "serialization should be sound");
+    } else {
+      assert_equals(rules[0][attribute], expected, "serialization should be canonical");
+    }
   }, `CSSScrollTimelineRule.${attribute} ${specified}`);
 }
 
@@ -131,39 +135,57 @@
   'orientation descriptor',
   `@scroll-timeline timeline { orientation: inline; }`);
 
+// https://github.com/w3c/csswg-drafts/issues/6617
 test_csstext(
-  'start descriptor (px)',
-  `@scroll-timeline timeline { start: 100px; }`);
+  'scroll-offsets descriptor (none)',
+  `@scroll-timeline timeline { scroll-offsets: none; }`,
+  `@scroll-timeline timeline { scroll-offsets: none; }`,);
 
 test_csstext(
-  'start descriptor (offset)',
-  `@scroll-timeline timeline { start: selector(#bar); }`);
+  'scroll-offsets descriptor (auto)',
+  `@scroll-timeline timeline { scroll-offsets: auto; }`);
 
 test_csstext(
-  'start descriptor (offset with edge)',
-  `@scroll-timeline timeline { start: selector(#bar) start; }`);
+  'scroll-offsets descriptor (container-based offset, px)',
+  `@scroll-timeline timeline { scroll-offsets: 100px; }`);
 
 test_csstext(
-  'start descriptor (offset with threshold)',
-  `@scroll-timeline timeline { start: selector(#bar) 1; }`);
+  'scroll-offsets descriptor (container-based offset, percentage)',
+  `@scroll-timeline timeline { scroll-offsets: 100%; }`);
 
 test_csstext(
-  'start descriptor (offset with edge and threshold)',
-  `@scroll-timeline timeline { start: selector(#bar) start 1; }`);
+  'scroll-offsets descriptor (element offset)',
+  `@scroll-timeline timeline { scroll-offsets: selector(#bar); }`);
 
 test_csstext(
-  'start descriptor (offset with threshold and edge)',
-  `@scroll-timeline timeline { start: selector(#bar) 1 start; }`,
-  `@scroll-timeline timeline { start: selector(#bar) start 1; }`);
+  'scroll-offsets descriptor (element offset with edge)',
+  `@scroll-timeline timeline { scroll-offsets: selector(#bar) start; }`);
+
+test_csstext(
+  'scroll-offsets descriptor (element offset with threshold)',
+  `@scroll-timeline timeline { scroll-offsets: selector(#bar) 1; }`);
+
+test_csstext(
+  'scroll-offsets descriptor (element offset with edge and threshold)',
+  `@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }`);
+
+test_csstext(
+  'scroll-offsets descriptor (element offset with threshold and edge)',
+  `@scroll-timeline timeline { scroll-offsets: selector(#bar) 1 start; }`,
+  `@scroll-timeline timeline { scroll-offsets: selector(#bar) start 1; }`);
+
+test_csstext(
+  'scroll-offsets descriptor (multiple offsets)',
+  `@scroll-timeline timeline { scroll-offsets: auto, selector(#bar) start 1; }`);
 
 test_csstext(
   'defaults',
-  `@scroll-timeline timeline { source: none; orientation: auto; start: auto; end: auto; }`);
+  `@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }`);
 
 test_csstext(
   'order',
-  `@scroll-timeline timeline { orientation: auto; source: none; end: auto; start: auto; }`,
-  `@scroll-timeline timeline { source: none; orientation: auto; start: auto; end: auto; }`);
+  `@scroll-timeline timeline { orientation: auto; source: auto; scroll-offsets: none; }`,
+  `@scroll-timeline timeline { source: auto; orientation: auto; scroll-offsets: none; }`);
 
 // CSSScrollTimelineRule.source
 
@@ -179,16 +201,16 @@
 test_source('selector(#a\\9 b)');
 test_source('auto');
 
-test_source('#foo', 'none');
-test_source('', 'none');
-test_source('element(#foo)', 'none');
-test_source('selector(#foo more)', 'none');
-test_source('selector(html)', 'none');
-test_source('selector(foo)', 'none');
-test_source('selector(:before)', 'none');
-test_source('selector(*)', 'none');
-test_source('selector(.a)', 'none');
-test_source('selector(.a, .b)', 'none');
+test_source('#foo', 'auto');
+test_source('', 'auto');
+test_source('element(#foo)', 'auto');
+test_source('selector(#foo more)', 'auto');
+test_source('selector(html)', 'auto');
+test_source('selector(foo)', 'auto');
+test_source('selector(:before)', 'auto');
+test_source('selector(*)', 'auto');
+test_source('selector(.a)', 'auto');
+test_source('selector(.a, .b)', 'auto');
 
 // CSSScrollTimelineRule.orientation
 
@@ -208,30 +230,30 @@
 test_orientation('10px', 'auto');
 test_orientation('red', 'auto');
 
-// CSSScrollTimelineRule.start
-// CSSScrollTimelineRule.end
+// CSSScrollTimelineRule.scrollOffsets
 
 function test_offsets(specified, expected) {
-  test_descriptor('start', specified, expected);
-  test_descriptor('end', specified, expected);
+  test_descriptor('scroll-offsets', specified, expected);
 }
 
+test_offsets('none');
+test_offsets(' none ', 'none');
+test_offsets('', 'none');
+test_offsets('red', 'none');
+test_offsets('#fff', 'none');
+test_offsets('unset', 'none');
+test_offsets('unknown(#foo)', 'none');
+test_offsets('start', 'none');
+test_offsets('end', 'none');
+test_offsets('3', 'none');
+test_offsets('selector(#foo) 3 start 10', 'none');
+test_offsets('0%, 100%, selector(.a)', 'none');
+test_offsets('selector(#foo) 3 end, start', 'none');
+
 test_offsets('auto');
-test_offsets(' auto ', 'auto');
-test_offsets('10px',);
-test_offsets(' 10px ', '10px');
 test_offsets('10em');
 test_offsets('10%');
-test_offsets('calc(1px + 1%)');
-
-test_offsets('', 'auto');
-test_offsets('red', 'auto');
-test_offsets('#fff', 'auto');
-test_offsets('unset', 'auto');
-test_offsets('unknown(#foo)', 'auto');
-test_offsets('start', 'auto');
-test_offsets('end', 'auto');
-test_offsets('3', 'auto');
+test_offsets('calc(1px + 1%)', ['calc(1px + 1%)', 'calc(1% + 1px)']);
 test_offsets('selector(#foo)');
 test_offsets(' selector(#foo)', 'selector(#foo)');
 test_offsets('selector(#foo) start');
@@ -241,5 +263,11 @@
 test_offsets('selector(#foo) end');
 test_offsets('selector(#foo) end 3');
 test_offsets('selector(#foo) 3 end', 'selector(#foo) end 3');
+test_offsets(' auto , auto ', 'auto, auto');
+test_offsets('10%, 100px');
+test_offsets('auto, 100%');
+test_offsets('0%, selector(  #foo)  3  end  ', "0%, selector(#foo) end 3");
+test_offsets('selector(#foo) end 3, selector(#bar)');
+test_offsets('0%, auto, selector(#foo) start, auto, selector(#bar) 12.3');
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/focus/blur-on-shadow-host-delegatesFocus.html b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/blur-on-shadow-host-delegatesFocus.html
new file mode 100644
index 0000000..289b554
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/shadow-dom/focus/blur-on-shadow-host-delegatesFocus.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: Blur on shadow host</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<div id="host">
+  <input id="slotted">
+</div>
+
+<script>
+const host = document.getElementById("host");
+
+const shadowRoot = host.attachShadow({ mode: "open", delegatesFocus: true });
+
+shadowRoot.innerHTML = "<input><slot>"
+
+test(function() {
+  host.focus();
+  assert_equals(document.activeElement, host);
+  assert_equals(shadowRoot.activeElement, shadowRoot.querySelector("input"));
+  host.blur();
+  assert_equals(document.activeElement, document.body);
+  assert_equals(shadowRoot.activeElement, null);
+}, "Calling blur() on shadow host with delegatesFocus should remove the focus.");
+
+test(function() {
+  const slotted = document.getElementById("slotted");
+  slotted.focus();
+  assert_equals(document.activeElement, slotted);
+  assert_equals(shadowRoot.activeElement, null)
+  host.blur();
+  assert_equals(document.activeElement, slotted);
+  assert_equals(shadowRoot.activeElement, null)
+}, "Calling blur() on shadow host with delegatesFocus when the focus is on a slotted element should not remove the focus.");
+</script>
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt b/third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt
similarity index 73%
rename from third_party/blink/web_tests/platform/linux/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt
rename to third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt
index 4ddf8eb..0bed6c93 100644
--- a/third_party/blink/web_tests/platform/linux/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
 FAIL share() can be disabled by permissions policy promise_rejects_dom: function "function() { throw e }" threw object "TypeError: Failed to execute 'share' on 'Navigator': No known share data fields supplied. If using only new fields (other than title, text and url), you must feature-detect them first." that is not a DOMException NotAllowedError: property "code" is equal to undefined, expected 0
-FAIL canShare() can be disabled by permissions policy promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'bind')"
+FAIL canShare() can be disabled by permissions policy assert_false: not allowed to share expected false got true
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub.html b/third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub.html
index 93cb444..e9ea9039 100644
--- a/third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub.html
+++ b/third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub.html
@@ -11,14 +11,16 @@
   </head>
   <body>
     <script>
-      promise_test(async t => {
+      promise_test(async (t) => {
         await test_driver.bless("web share");
-
         await promise_rejects_dom(t, "NotAllowedError", navigator.share({}));
       }, "share() can be disabled by permissions policy");
 
-      promise_test(async t => {
-        await promise_rejects_dom(t, "NotAllowedError", navigator.canShare({}));
+      test((t) => {
+        assert_false(
+          navigator.canShare({ text: "foo" }),
+          "not allowed to share"
+        );
       }, "canShare() can be disabled by permissions policy");
     </script>
   </body>
diff --git a/third_party/blink/web_tests/external/wpt/web-share/disabled-by-feature-policy.https.sub.html.headers b/third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub.html.headers
similarity index 100%
rename from third_party/blink/web_tests/external/wpt/web-share/disabled-by-feature-policy.https.sub.html.headers
rename to third_party/blink/web_tests/external/wpt/web-share/disabled-by-permissions-policy.https.sub.html.headers
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-connectionSetup.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-connectionSetup.html
index d2cde59..cedc2ca 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-connectionSetup.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-addIceCandidate-connectionSetup.html
@@ -1,4 +1,5 @@
 <!doctype html>
+<meta name="timeout" content="long">
 <title>Test RTCPeerConnection.prototype.addIceCandidate</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -50,10 +51,11 @@
   await pc2.setLocalDescription(answer);
   await pc2GatheredCandidates;
   // Add candidates to pc1, ensuring that it goes to "connecting" state before "connected".
-  for (let candidate of candidates2to1) {
-    await pc1.addIceCandidate(candidate);
-  }
+  // We do not iterate/await because repeatedly awaiting while we serially add
+  // the candidates opens the opportunity to miss the 'connecting' transition.
+  const addCandidatesDone = Promise.all(candidates2to1.map(c => pc1.addIceCandidate(c)));
   await waitForState(transceiver.sender.transport, 'connecting');
+  await addCandidatesDone;
   await waitForState(transceiver.sender.transport, 'connected');
 }, 'Candidates are added at PC1; connection should work');
 
@@ -81,9 +83,9 @@
   await pc2.setLocalDescription(answer);
   await pc1GatheredCandidates;
   // Add candidates to pc2
-  for (let candidate of candidates1to2) {
-    await pc2.addIceCandidate(candidate);
-  }
+  // We do not iterate/await because repeatedly awaiting while we serially add
+  // the candidates opens the opportunity to miss the ICE state transitions.
+  await Promise.all(candidates1to2.map(c => pc2.addIceCandidate(c)));
   await waitForState(transceiver.sender.transport, 'connected');
 }, 'Candidates are added at PC2; connection should work');
 
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html
index f26a93e..8062618 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-getStats.https.html
@@ -1,5 +1,6 @@
 <!doctype html>
 <meta charset=utf-8>
+<meta name="timeout" content="long">
 <title>RTCPeerConnection.prototype.getStats</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html
index 0343655..08f206f 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-ondatachannel.html
@@ -1,5 +1,6 @@
 <!doctype html>
 <meta charset=utf-8>
+<meta name="timeout" content="long">
 <title>RTCPeerConnection.prototype.ondatachannel</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-perfect-negotiation-helper.js b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-perfect-negotiation-helper.js
index 28c476e..ed647bb 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-perfect-negotiation-helper.js
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-perfect-negotiation-helper.js
@@ -36,7 +36,7 @@
   try {
     pc.addEventListener("icecandidate", ({candidate}) => send(other,
                                                               {candidate}));
-    let makingOffer = false, ignoreOffer = false;
+    let makingOffer = false, ignoreIceCandidateFailures = false;
     let srdAnswerPending = false;
     pc.addEventListener("negotiationneeded", async () => {
       try {
@@ -63,14 +63,16 @@
           let isStable =
               pc.signalingState == "stable" ||
               (pc.signalingState == "have-local-offer" && srdAnswerPending);
-          ignoreOffer = description.type == "offer" && !polite &&
+          const ignoreOffer = description.type == "offer" && !polite &&
                          (makingOffer || !isStable);
           if (ignoreOffer) {
+            ignoreIceCandidateFailures = true;
             return;
           }
           if (description.type == "answer")
             srdAnswerPending = true;
           await pc.setRemoteDescription(description);
+          ignoreIceCandidateFailures = false;
           srdAnswerPending = false;
           if (description.type == "offer") {
             assert_equals(pc.signalingState, "have-remote-offer", "Remote offer");
@@ -88,7 +90,7 @@
           try {
             await pc.addIceCandidate(candidate);
           } catch (e) {
-            if (!ignoreOffer) throw e;
+            if (!ignoreIceCandidateFailures) throw e;
           }
         } else if (run) {
           send(window.parent, {[run.id]: await commands[run.cmd]() || 0});
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt
index 9d4d4969b..7f2351af 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
+PASS restartIce() has no effect on a closed peer connection
 FAIL restartIce() does not trigger negotiation ahead of initial negotiation assert_equals: No negotiationneeded event expected (undefined) undefined but got (object) object "[object Event]"
 PASS restartIce() has no effect on initial negotiation
 PASS restartIce() fires negotiationneeded after initial negotiation
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https.html
index 0e4ecf6..45a04d3 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-restartIce.https.html
@@ -51,8 +51,8 @@
   await pc2.setLocalDescription(pc1.remoteDescription); // End on pc2. No race
 }
 
-async function assertNoNegotiationNeeded(t, pc) {
-  assert_equals(pc.signalingState, "stable", "In stable state");
+async function assertNoNegotiationNeeded(t, pc, state = "stable") {
+  assert_equals(pc.signalingState, state, `In ${state} state`);
   const event = await Promise.race([
     new Promise(r => pc.onnegotiationneeded = r),
     new Promise(r => t.step_timeout(r, 10))
@@ -74,6 +74,13 @@
 }
 
 promise_test(async t => {
+  const pc = new RTCPeerConnection();
+  pc.close();
+  pc.restartIce();
+  await assertNoNegotiationNeeded(t, pc, "closed");
+}, "restartIce() has no effect on a closed peer connection");
+
+promise_test(async t => {
   const pc1 = new RTCPeerConnection();
   const pc2 = new RTCPeerConnection();
   t.add_cleanup(() => pc1.close());
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt
index 12a8febb..a83779ea 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-expected.txt
@@ -4,5 +4,7 @@
 PASS Negotiation should fire signalingsstate events
 PASS Calling setRemoteDescription() again after one round of remote-offer/local-answer should succeed
 PASS Switching role from offerer to answerer after going back to stable state should succeed
+PASS Closing on setRemoteDescription() neither resolves nor rejects
+PASS Closing on rollback neither resolves nor rejects
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html
index 3f335d7..c170f76 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html
@@ -141,11 +141,31 @@
     assert_session_desc_similar(pc.currentRemoteDescription, answer);
   }, 'Switching role from offerer to answerer after going back to stable state should succeed');
 
-  /*
-    TODO
-    4.3.2.  setRemoteDescription
-      - If an a=identity attribute is present in the session description, the browser
-        validates the identity assertion.
-   */
+  promise_test(async t => {
+    const pc = new RTCPeerConnection();
+    t.add_cleanup(() => pc.close());
+    const offer = await pc.createOffer();
+    const p = Promise.race([
+      pc.setRemoteDescription(offer),
+      new Promise(r => t.step_timeout(() => r("timeout"), 200))
+    ]);
+    pc.close();
+    assert_equals(await p, "timeout");
+    assert_equals(pc.signalingState, "closed", "In closed state");
+  }, 'Closing on setRemoteDescription() neither resolves nor rejects');
+
+  promise_test(async t => {
+    const pc = new RTCPeerConnection();
+    t.add_cleanup(() => pc.close());
+    const offer = await pc.createOffer();
+    await pc.setLocalDescription(offer);
+    const p = Promise.race([
+      pc.setRemoteDescription(offer),
+      new Promise(r => t.step_timeout(() => r("timeout"), 200))
+    ]);
+    pc.close();
+    assert_equals(await p, "timeout");
+    assert_equals(pc.signalingState, "closed", "In closed state");
+  }, 'Closing on rollback neither resolves nor rejects');
 
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/no-media-call-expected.txt b/third_party/blink/web_tests/external/wpt/webrtc/no-media-call-expected.txt
new file mode 100644
index 0000000..2de564ff
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/webrtc/no-media-call-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Can set up a basic WebRTC call with no data. assert_equals: expected (number) 1 but got (object) object "[object RTCRtpSender]"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/no-media-call.html b/third_party/blink/web_tests/external/wpt/webrtc/no-media-call.html
index 9d25985..bdd42f6f 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/no-media-call.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/no-media-call.html
@@ -43,8 +43,10 @@
   };
 
   var onAnswerCreated = test.step_func(function(answer) {
-    gSecondConnection.setLocalDescription(answer, ignoreSuccess,
-                                          failed('setLocalDescription second'));
+    gSecondConnection.setLocalDescription(answer, test.step_func(() => {
+        assert_equals(gSecondConnection.getSenders()[0], 1);
+        assert_not_equals(gSecondConnection.getSenders()[0].transport, null);
+    }), failed('setLocalDescription second'));
 
     // Similarly, this would go over the application's signaling solution.
     handleAnswer(answer.sdp);
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-demuxing.html b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-demuxing.html
index 1b8dce3b..de08b21 100644
--- a/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-demuxing.html
+++ b/third_party/blink/web_tests/external/wpt/webrtc/protocol/rtp-demuxing.html
@@ -1,5 +1,6 @@
 <!doctype html>
 <meta charset=utf-8>
+<meta name="timeout" content="long">
 <title>RTCPeerConnection payload type demuxing</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
rename to third_party/blink/web_tests/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
rename to third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
rename to third_party/blink/web_tests/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/win/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
rename to third_party/blink/web_tests/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/outline-offset-text-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/outline-offset-text-expected.txt
index 03d48a2..7a1f41ef 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/outline-offset-text-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/svg/outline-offset-text-expected.txt
@@ -6,8 +6,8 @@
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
       "invalidations": [
-        [102, 25, 162, 115],
-        [62, 25, 162, 115]
+        [103, 26, 160, 113],
+        [63, 26, 160, 113]
       ]
     }
   ]
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-expected.txt
index b4f23b8..6eca02d 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
index b4f23b8..6eca02d 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-expected.txt
index 47e56c8..14f72cc 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
index 47e56c8..14f72cc 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-expected.txt
index 1e68823..2412647c 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
index 1e68823..2412647c 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-expected.txt
index 51cd7ae..f0d7154 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
index 51cd7ae..f0d7154 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-expected.txt
index 2f73b1a..fa72fa1 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
index 2f73b1a..fa72fa1 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
index b1224223..6b3bd5f7 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
index b1224223..6b3bd5f7 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-expected.txt
index 1c63103..be6a76e 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
index 1c63103..be6a76e 100644
--- a/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/backface-visibility-interop/paint/invalidation/svg/outline-offset-text-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/backface-visibility-interop/paint/invalidation/svg/outline-offset-text-expected.txt
new file mode 100644
index 0000000..7a1f41ef
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/backface-visibility-interop/paint/invalidation/svg/outline-offset-text-expected.txt
@@ -0,0 +1,15 @@
+{
+  "layers": [
+    {
+      "name": "Scrolling background of LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "invalidations": [
+        [103, 26, 160, 113],
+        [63, 26, 160, 113]
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/transform-interop-disabled/paint/invalidation/svg/outline-offset-text-expected.txt b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/transform-interop-disabled/paint/invalidation/svg/outline-offset-text-expected.txt
new file mode 100644
index 0000000..7a1f41ef
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/composite-after-paint/virtual/transform-interop-disabled/paint/invalidation/svg/outline-offset-text-expected.txt
@@ -0,0 +1,15 @@
+{
+  "layers": [
+    {
+      "name": "Scrolling background of LayoutView #document",
+      "bounds": [800, 600],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "invalidations": [
+        [103, 26, 160, 113],
+        [63, 26, 160, 113]
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/svg/foreignObject/svg-document-in-html-document-expected.png
new file mode 100644
index 0000000..085e2c6
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/svg/foreignObject/svg-document-in-html-document-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/synchronous_html_parser/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/synchronous_html_parser/svg/foreignObject/svg-document-in-html-document-expected.png
new file mode 100644
index 0000000..085e2c6
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/disable-layout-ng/virtual/synchronous_html_parser/svg/foreignObject/svg-document-in-html-document-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/editing/selection/display-table-text-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/editing/selection/display-table-text-expected.txt
index 2eff3471..3860b112 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/editing/selection/display-table-text-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/editing/selection/display-table-text-expected.txt
@@ -7,7 +7,7 @@
       LayoutNGTable {DIV} at (0,0) size 537x27
         LayoutNGTableSection (anonymous) at (0,0) size 537x27
           LayoutNGTableRow (anonymous) at (0,0) size 537x27
-            LayoutNGTableCellNew (anonymous) at (0,0) size 537x27 [r=0 c=0 rs=1 cs=1]
+            LayoutNGTableCell (anonymous) at (0,0) size 537x27 [r=0 c=0 rs=1 cs=1]
               LayoutText {#text} at (0,0) size 537x26
                 text run at (0,0) width 537: "Only the third word in this sentence should be selected."
 selection start: position 9 of child 0 {#text} of child 1 {DIV} of body
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/outline-offset-text-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/outline-offset-text-expected.txt
index a550977..6cff288 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/outline-offset-text-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/outline-offset-text-expected.txt
@@ -6,8 +6,8 @@
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
       "invalidations": [
-        [143, 26, 263, 194],
-        [83, 26, 263, 194]
+        [144, 27, 261, 192],
+        [84, 27, 261, 192]
       ]
     }
   ]
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/zoom-foreignObject-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/zoom-foreignObject-expected.png
index 1d5a3194..834e68b 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/svg/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-expected.txt
index 5123585ac..28139a4cc 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
index 5123585ac..28139a4cc 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-expected.txt
index a14854032..119bb8f 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
index a14854032..119bb8f 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-expected.txt
index c1eeaa6..9abb9b1 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [88, 96],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
index c1eeaa6..9abb9b1 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [88, 96],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-expected.txt
index 7e49c6f..cebc541a 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
index 7e49c6f..cebc541a 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-expected.txt
index 35c820c..e118eac2 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
index 35c820c..e118eac2 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
index e4f1a366..1a55d68 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
index e4f1a366..1a55d68 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-expected.txt
index 1766678..6c661ee6 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
index 1766678..6c661ee6 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [88, 96],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/scroll-inside-table-cell-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/scroll-inside-table-cell-expected.txt
index 43d6374..62e5be3 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/scroll-inside-table-cell-expected.txt
+++ b/third_party/blink/web_tests/flag-specific/highdpi/paint/invalidation/table/scroll-inside-table-cell-expected.txt
@@ -7,7 +7,7 @@
       "backgroundColor": "#FF0000"
     },
     {
-      "name": "LayoutNGTableCellNew (relative positioned) TD id='cellToScroll' class='relative'",
+      "name": "LayoutNGTableCell (relative positioned) TD id='cellToScroll' class='relative'",
       "bounds": [681, 704],
       "transform": 1
     },
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/svg/foreignObject/svg-document-in-html-document-expected.png
index 2de3e53..9b5848f 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/svg/foreignObject/svg-document-in-html-document-expected.png
+++ b/third_party/blink/web_tests/flag-specific/highdpi/svg/foreignObject/svg-document-in-html-document-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/svg/zoom/page/zoom-foreignObject-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/svg/zoom/page/zoom-foreignObject-expected.png
index 1bd24ac9..e8a6cdcb 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/svg/zoom/page/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/flag-specific/highdpi/svg/zoom/page/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/svg/outline-offset-text-expected.txt b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/svg/outline-offset-text-expected.txt
new file mode 100644
index 0000000..6cff288
--- /dev/null
+++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/svg/outline-offset-text-expected.txt
@@ -0,0 +1,15 @@
+{
+  "layers": [
+    {
+      "name": "Scrolling Contents Layer",
+      "bounds": [1200, 900],
+      "contentsOpaque": true,
+      "backgroundColor": "#FFFFFF",
+      "invalidations": [
+        [144, 27, 261, 192],
+        [84, 27, 261, 192]
+      ]
+    }
+  ]
+}
+
diff --git a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png
index 1d5a3194..834e68b 100644
--- a/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/flag-specific/highdpi/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/editing/selection/display-table-text-expected.txt b/third_party/blink/web_tests/platform/linux/editing/selection/display-table-text-expected.txt
index 6aa5bfa..7e3d68e 100644
--- a/third_party/blink/web_tests/platform/linux/editing/selection/display-table-text-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/editing/selection/display-table-text-expected.txt
@@ -7,7 +7,7 @@
       LayoutNGTable {DIV} at (0,0) size 348x20
         LayoutNGTableSection (anonymous) at (0,0) size 348x20
           LayoutNGTableRow (anonymous) at (0,0) size 348x20
-            LayoutNGTableCellNew (anonymous) at (0,0) size 348x20 [r=0 c=0 rs=1 cs=1]
+            LayoutNGTableCell (anonymous) at (0,0) size 348x20 [r=0 c=0 rs=1 cs=1]
               LayoutText {#text} at (0,0) size 348x19
                 text run at (0,0) width 348: "Only the third word in this sentence should be selected."
 selection start: position 9 of child 0 {#text} of child 1 {DIV} of body
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/zoom-foreignObject-expected.png
index 4130567..0c16e15e 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/svg/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-expected.txt
index 2623943..c6816917 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
index 2623943..c6816917 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-expected.txt
index 4459c74..9a38376 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
index 4459c74..9a38376 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-expected.txt
index 4a3b5f2..1fd8dc83 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
index 4a3b5f2..1fd8dc83 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt
index 45205f3..b243d62 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
index 45205f3..b243d62 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-expected.txt
index 4dcc052b..ed92a3b 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
index 4dcc052b..ed92a3b 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
index d6c38c5..f31d691 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
index d6c38c5..f31d691 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt
index 11a36425..bdfab7f2 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
index 11a36425..bdfab7f2 100644
--- a/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/linux/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/linux/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/blink/web_tests/platform/linux/svg/foreignObject/svg-document-in-html-document-expected.png
index 085e2c6..354800c 100644
--- a/third_party/blink/web_tests/platform/linux/svg/foreignObject/svg-document-in-html-document-expected.png
+++ b/third_party/blink/web_tests/platform/linux/svg/foreignObject/svg-document-in-html-document-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-foreignObject-expected.png
index d709ed37..57f04140 100644
--- a/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/linux/svg/zoom/page/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/linux/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png
index 4130567..0c16e15e 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/backface-visibility-interop/paint/invalidation/svg/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/synchronous_html_parser/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/blink/web_tests/platform/linux/virtual/synchronous_html_parser/svg/foreignObject/svg-document-in-html-document-expected.png
new file mode 100644
index 0000000..354800c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/linux/virtual/synchronous_html_parser/svg/foreignObject/svg-document-in-html-document-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/synchronous_html_parser/svg/zoom/page/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/linux/virtual/synchronous_html_parser/svg/zoom/page/zoom-foreignObject-expected.png
index d709ed37..57f04140 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/synchronous_html_parser/svg/zoom/page/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/synchronous_html_parser/svg/zoom/page/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/linux/virtual/transform-interop-disabled/paint/invalidation/svg/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/linux/virtual/transform-interop-disabled/paint/invalidation/svg/zoom-foreignObject-expected.png
index 4130567..0c16e15e 100644
--- a/third_party/blink/web_tests/platform/linux/virtual/transform-interop-disabled/paint/invalidation/svg/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/linux/virtual/transform-interop-disabled/paint/invalidation/svg/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
deleted file mode 100644
index 3263683..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/Create-protocols-repeated-case-insensitive.any_wss-expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a testharness.js-based test.
-FAIL Create WebSocket - Pass a valid URL and an array of protocol strings with repeated values but different case - SYNTAX_ERR is thrown assert_throws_dom: function "function() {
-    wsocket = CreateWebSocketWithRepeatedProtocolsCaseInsensitive()
-  }" did not throw
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
deleted file mode 100644
index 97ce540..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/basic-auth.any.sharedworker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL HTTP basic authentication should work with WebSockets assert_unreached: open should succeed Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
deleted file mode 100644
index 97ce540..0000000
--- a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/basic-auth.any.worker_wpt_flags=h2-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL HTTP basic authentication should work with WebSockets assert_unreached: open should succeed Reached unreachable code
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/editing/other/editing-around-select-element.tentative_insertText-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/editing/other/editing-around-select-element.tentative_insertText-expected.txt
new file mode 100644
index 0000000..249bdd21
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/editing/other/editing-around-select-element.tentative_insertText-expected.txt
@@ -0,0 +1,40 @@
+This is a testharness.js-based test.
+PASS Test execCommand with selection around select element
+FAIL execCommand(insertText, false, "XYZ") in <div contenteditable><p>ab[c</p><select><option>d]ef</option></select></div>: shouldn't modify in <option> assert_in_array: value "<div contenteditable><p>abXYZc</p><select><option>def</option></select></div>" not in array ["<div contenteditable><p>abc</p><select><option>def</option></select></div>", "<div contenteditable><p>abXYZ</p><select><option>def</option></select></div>"]
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select><option>d[]ef</option></select></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><select><option>ab[c</option></select><p>d]ef</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select><option>{}def</option></select><p>ghi</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select><option>def{}</option></select><p>ghi</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select><option>{def}</option></select><p>ghi</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select><option>{def</option><option>ghi}</option></select><p>jkl</p></div>: shouldn't join <option>s
+FAIL execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select>{<option>def</option>}<option>ghi</option></select><p>jkl</p></div>: shouldn't delete <option> assert_equals: expected "<div contenteditable><p>abc</p><select><option>def</option><option>ghi</option></select><p>jkl</p></div>" but got "<div contenteditable><p>abc</p>XYZ<select><option>def</option><option>ghi</option></select><p>jkl</p></div>"
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select><option>def</option>{<option>ghi</option>}</select><p>jkl</p></div>: shouldn't delete <option>
+FAIL execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select>{<option>def</option><option>ghi</option>}</select><p>jkl</p></div>: shouldn't delete <option>s nor <select> assert_equals: expected "<div contenteditable><p>abc</p><select><option>def</option><option>ghi</option></select><p>jkl</p></div>" but got "<div contenteditable><p>abc</p><p>XYZjkl</p></div>"
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select><optgroup>{<option>def</option><option>ghi</option>}</optgroup></select><p>jkl</p></div>: shouldn't delete <option>, <optgroup> nor <select>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p>{<select><option>def</option><option>ghi</option></select>}<p>jkl</p></div>: <select> element itself should be removable
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p>{<select><optgroup><option>def</option><option>ghi</option></optgroup></select>}<p>jkl</p></div>: <select> element itself should be removable
+PASS execCommand(insertText, false, "XYZ") in <select contenteditable>{<option>abc</option><option>def</option>}</select>: shouldn't delete <option>s
+PASS execCommand(insertText, false, "XYZ") in <select><option contenteditable>{abc}</option><option>def</option></select>: shouldn't modify <option>
+PASS execCommand(insertText, false, "XYZ") in <select><optgroup contenteditable>{<option>abc</option><option>def</option>}</optgroup></select>: shouldn't delete <option>s
+PASS execCommand(insertText, false, "XYZ") in <select><optgroup contenteditable><option>{abc}</option><option>def</option></optgroup></select>: shouldn't delete <option>s nor optgroup
+FAIL execCommand(insertText, false, "XYZ") in <div contenteditable><p>ab[c</p><select multiple><option>d]ef</option></select></div>: shouldn't modify in <option> assert_in_array: value "<div contenteditable><p>abXYZc</p><select multiple><option>def</option></select></div>" not in array ["<div contenteditable><p>abc</p><select multiple><option>def</option></select></div>", "<div contenteditable><p>abXYZ</p><select multiple><option>def</option></select></div>"]
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple><option>d[]ef</option></select></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><select multiple><option>ab[c</option></select><p>d]ef</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple><option>{}def</option></select><p>ghi</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple><option>def{}</option></select><p>ghi</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple><option>{def}</option></select><p>ghi</p></div>: shouldn't modify in <option>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple><option>{def</option><option>ghi}</option></select><p>jkl</p></div>: shouldn't join <option>s
+FAIL execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple>{<option>def</option>}<option>ghi</option></select><p>jkl</p></div>: shouldn't delete <option> assert_equals: expected "<div contenteditable><p>abc</p><select multiple><option>def</option><option>ghi</option></select><p>jkl</p></div>" but got "<div contenteditable><p>abc</p>XYZ<select multiple><option>def</option><option>ghi</option></select><p>jkl</p></div>"
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple><option>def</option>{<option>ghi</option>}</select><p>jkl</p></div>: shouldn't delete <option>
+FAIL execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple>{<option>def</option><option>ghi</option>}</select><p>jkl</p></div>: shouldn't delete <option>s nor <select multiple> assert_equals: expected "<div contenteditable><p>abc</p><select multiple><option>def</option><option>ghi</option></select><p>jkl</p></div>" but got "<div contenteditable><p>abc</p><p>XYZjkl</p></div>"
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p><select multiple><optgroup>{<option>def</option><option>ghi</option>}</optgroup></select><p>jkl</p></div>: shouldn't delete <option>, <optgroup> nor <select multiple>
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p>{<select multiple><option>def</option><option>ghi</option></select>}<p>jkl</p></div>: <select multiple> element itself should be removable
+PASS execCommand(insertText, false, "XYZ") in <div contenteditable><p>abc</p>{<select multiple><optgroup><option>def</option><option>ghi</option></optgroup></select>}<p>jkl</p></div>: <select multiple> element itself should be removable
+PASS execCommand(insertText, false, "XYZ") in <select multiple contenteditable>{<option>abc</option><option>def</option>}</select>: shouldn't delete <option>s
+PASS execCommand(insertText, false, "XYZ") in <select multiple><option contenteditable>{abc}</option><option>def</option></select>: shouldn't modify <option>
+PASS execCommand(insertText, false, "XYZ") in <select multiple><optgroup contenteditable>{<option>abc</option><option>def</option>}</optgroup></select>: shouldn't delete <option>s
+PASS execCommand(insertText, false, "XYZ") in <select multiple><optgroup contenteditable><option>{abc}</option><option>def</option></optgroup></select>: shouldn't delete <option>s nor optgroup
+PASS execCommand(insertText, false, "XYZ") in <optgroup contenteditable><option>{abc}</option><option>def</option></optgroup>: shouldn't delete <option>s nor optgroup
+PASS execCommand(insertText, false, "XYZ") in <option contenteditable>{abc}</option>: shouldn't modify <option>
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
similarity index 100%
rename from third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
rename to third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/backpressure-send.any.serviceworker_wpt_flags=h2-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt b/third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt
similarity index 100%
copy from third_party/blink/web_tests/platform/mac-mac10.15/external/wpt/websockets/stream/tentative/backpressure-send.any.worker_wpt_flags=h2-expected.txt
copy to third_party/blink/web_tests/platform/mac-mac11-arm64/external/wpt/websockets/stream/tentative/backpressure-send.any_wpt_flags=h2-expected.txt
diff --git a/third_party/blink/web_tests/platform/mac/editing/selection/display-table-text-expected.txt b/third_party/blink/web_tests/platform/mac/editing/selection/display-table-text-expected.txt
index 69c57dce..8c862cd 100644
--- a/third_party/blink/web_tests/platform/mac/editing/selection/display-table-text-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/editing/selection/display-table-text-expected.txt
@@ -7,7 +7,7 @@
       LayoutNGTable {DIV} at (0,0) size 354.59x18
         LayoutNGTableSection (anonymous) at (0,0) size 354.59x18
           LayoutNGTableRow (anonymous) at (0,0) size 354.59x18
-            LayoutNGTableCellNew (anonymous) at (0,0) size 354.59x18 [r=0 c=0 rs=1 cs=1]
+            LayoutNGTableCell (anonymous) at (0,0) size 354.59x18 [r=0 c=0 rs=1 cs=1]
               LayoutText {#text} at (0,0) size 355x18
                 text run at (0,0) width 355: "Only the third word in this sentence should be selected."
 selection start: position 9 of child 0 {#text} of child 1 {DIV} of body
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt
new file mode 100644
index 0000000..a2607703
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if ja and loose assert_approx_equals: expected 47.53125 +/- 1 but got 77.53125
+FAIL 2025  TWO DOT LEADER may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt
new file mode 100644
index 0000000..76e18040
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 91.625 +/- 1 but got 61.625
+FAIL 20AC  EURO SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 91.59375 +/- 1 but got 61.59375
+FAIL 2116  NUMERO SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99.75 +/- 1 but got 69.75
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt
new file mode 100644
index 0000000..b11dbe4
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 91.625 +/- 1 but got 61.625
+FAIL 20AC  EURO SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 91.59375 +/- 1 but got 61.59375
+FAIL 2116  NUMERO SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99.75 +/- 1 but got 69.75
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt
new file mode 100644
index 0000000..5ee5905
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if de and loose assert_approx_equals: expected 47.53125 +/- 1 but got 77.53125
+FAIL 2025  TWO DOT LEADER may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt
new file mode 100644
index 0000000..4ce9129
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if loose assert_approx_equals: expected 47.53125 +/- 1 but got 77.53125
+FAIL 2025  TWO DOT LEADER may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt
new file mode 100644
index 0000000..69a21cf
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if zh and loose assert_approx_equals: expected 47.53125 +/- 1 but got 77.53125
+FAIL 2025  TWO DOT LEADER may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt
new file mode 100644
index 0000000..277629d
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 91.625 +/- 1 but got 61.625
+FAIL 20AC  EURO SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 91.59375 +/- 1 but got 61.59375
+FAIL 2116  NUMERO SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99.75 +/- 1 but got 69.75
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt
new file mode 100644
index 0000000..73fda38c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/mac/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 91.625 +/- 1 but got 61.625
+FAIL 20AC  EURO SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 91.59375 +/- 1 but got 61.59375
+FAIL 2116  NUMERO SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99.75 +/- 1 but got 69.75
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt
deleted file mode 100644
index 4ddf8eb..0000000
--- a/third_party/blink/web_tests/platform/mac/external/wpt/web-share/disabled-by-permissions-policy.https.sub-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-This is a testharness.js-based test.
-FAIL share() can be disabled by permissions policy promise_rejects_dom: function "function() { throw e }" threw object "TypeError: Failed to execute 'share' on 'Navigator': No known share data fields supplied. If using only new fields (other than title, text and url), you must feature-detect them first." that is not a DOMException NotAllowedError: property "code" is equal to undefined, expected 0
-FAIL canShare() can be disabled by permissions policy promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'bind')"
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/outline-offset-text-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/outline-offset-text-expected.txt
index b281fb70..0b217e8 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/outline-offset-text-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/outline-offset-text-expected.txt
@@ -6,8 +6,8 @@
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
       "invalidations": [
-        [103, 23, 161, 118],
-        [63, 23, 161, 118]
+        [104, 24, 159, 116],
+        [64, 24, 159, 116]
       ]
     }
   ]
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/zoom-foreignObject-expected.png
index 705289c..9ba8d19 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/svg/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-expected.txt
index bb80aead..2e9aa721 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
index bb80aead..2e9aa721 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-expected.txt
index 1068a4c..1d70d4f0 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
index 1068a4c..1d70d4f0 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-expected.txt
index 400918a..2389273 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
index 400918a..2389273 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt
index 121746ec..6e49fb3 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
index 121746ec..6e49fb3 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-expected.txt
index 08b4be0ba..15567cf 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
index 08b4be0ba..15567cf 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
index bc67168..2aad60b4 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
index bc67168..2aad60b4 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt
index dbe6b082..9975a38 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
index dbe6b082..9975a38 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-inside-table-cell-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-inside-table-cell-expected.txt
index 492f0aa0..0ad07da8 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-inside-table-cell-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-inside-table-cell-expected.txt
@@ -7,7 +7,7 @@
       "backgroundColor": "#FF0000"
     },
     {
-      "name": "LayoutNGTableCellNew (relative positioned) TD id='cellToScroll' class='relative'",
+      "name": "LayoutNGTableCell (relative positioned) TD id='cellToScroll' class='relative'",
       "bounds": [454, 469],
       "transform": 1
     },
diff --git a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-relative-table-inside-table-cell-expected.txt b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-relative-table-inside-table-cell-expected.txt
index 596010a..9412cc0 100644
--- a/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-relative-table-inside-table-cell-expected.txt
+++ b/third_party/blink/web_tests/platform/mac/paint/invalidation/table/scroll-relative-table-inside-table-cell-expected.txt
@@ -8,7 +8,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew (relative positioned) TD id='cellToScroll' class='relative'",
+      "name": "LayoutNGTableCell (relative positioned) TD id='cellToScroll' class='relative'",
       "bounds": [454, 469],
       "transform": 2
     },
diff --git a/third_party/blink/web_tests/platform/mac/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/blink/web_tests/platform/mac/svg/foreignObject/svg-document-in-html-document-expected.png
index 51a6aee..7cacae2 100644
--- a/third_party/blink/web_tests/platform/mac/svg/foreignObject/svg-document-in-html-document-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/foreignObject/svg-document-in-html-document-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-foreignObject-expected.png
index 64e9652..2d4a184 100644
--- a/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/mac/svg/zoom/page/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/editing/selection/display-table-text-expected.txt b/third_party/blink/web_tests/platform/win/editing/selection/display-table-text-expected.txt
index d685b1d..c0c76fd 100644
--- a/third_party/blink/web_tests/platform/win/editing/selection/display-table-text-expected.txt
+++ b/third_party/blink/web_tests/platform/win/editing/selection/display-table-text-expected.txt
@@ -7,7 +7,7 @@
       LayoutNGTable {DIV} at (0,0) size 331x20
         LayoutNGTableSection (anonymous) at (0,0) size 331x20
           LayoutNGTableRow (anonymous) at (0,0) size 331x20
-            LayoutNGTableCellNew (anonymous) at (0,0) size 331x20 [r=0 c=0 rs=1 cs=1]
+            LayoutNGTableCell (anonymous) at (0,0) size 331x20 [r=0 c=0 rs=1 cs=1]
               LayoutText {#text} at (0,0) size 331x19
                 text run at (0,0) width 331: "Only the third word in this sentence should be selected."
 selection start: position 9 of child 0 {#text} of child 1 {DIV} of body
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt
new file mode 100644
index 0000000..dbe8507
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if ja and loose assert_approx_equals: expected 48 +/- 1 but got 78
+FAIL 2025  TWO DOT LEADER may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if ja and loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt
new file mode 100644
index 0000000..5ec1a473
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-normal-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 20AC  EURO SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 2116  NUMERO SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 100 +/- 1 but got 70
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if ja and normal assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt
new file mode 100644
index 0000000..913ef00
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/ja/css-text-line-break-ja-pr-strict-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 20AC  EURO SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 2116  NUMERO SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 100 +/- 1 but got 70
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if ja and strict assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt
new file mode 100644
index 0000000..d3c239c
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/other-lang/css-text-line-break-de-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if de and loose assert_approx_equals: expected 48 +/- 1 but got 78
+FAIL 2025  TWO DOT LEADER may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if de and loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt
new file mode 100644
index 0000000..2462a03
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/unknown-lang/css-text-line-break-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if loose assert_approx_equals: expected 48 +/- 1 but got 78
+FAIL 2025  TWO DOT LEADER may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt
new file mode 100644
index 0000000..9e8a8854
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-in-loose-expected.txt
@@ -0,0 +1,8 @@
+This is a testharness.js-based test.
+FAIL 2024  ONE DOT LEADER may appear at line start if zh and loose assert_approx_equals: expected 48 +/- 1 but got 78
+FAIL 2025  TWO DOT LEADER may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 2026  HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL 22EF  MIDLINE HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+FAIL FE19  PRESENTATION FORM FOR VERTICAL HORIZONTAL ELLIPSIS may appear at line start if zh and loose assert_approx_equals: expected 69 +/- 1 but got 99
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt
new file mode 100644
index 0000000..8005ba3
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-normal-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 20AC  EURO SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 2116  NUMERO SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 100 +/- 1 but got 70
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if zh and normal assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt
new file mode 100644
index 0000000..89017ed
--- /dev/null
+++ b/third_party/blink/web_tests/platform/win/external/wpt/css/css-text/i18n/zh/css-text-line-break-zh-pr-strict-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+FAIL 00B1  PLUS-MINUS SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 20AC  EURO SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 92 +/- 1 but got 62
+FAIL 2116  NUMERO SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 100 +/- 1 but got 70
+FAIL FE69  SMALL DOLLAR SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FF04  FULLWIDTH DOLLAR SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE1  FULLWIDTH POUND SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE5  FULLWIDTH YEN SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+FAIL FFE6  FULLWIDTH WON SIGN may NOT appear at line start if zh and strict assert_approx_equals: expected 99 +/- 1 but got 69
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/outline-offset-text-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/outline-offset-text-expected.txt
index 54584bb4d..f5c7654 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/outline-offset-text-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/outline-offset-text-expected.txt
@@ -6,8 +6,8 @@
       "contentsOpaque": true,
       "backgroundColor": "#FFFFFF",
       "invalidations": [
-        [102, 25, 162, 115],
-        [62, 25, 162, 115]
+        [103, 26, 160, 113],
+        [63, 26, 160, 113]
       ]
     }
   ]
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/zoom-foreignObject-expected.png
index 19ef50b..3689b48b 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/svg/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/svg/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-expected.txt
index 348b6059..a90a2c45 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
index 348b6059..a90a2c45 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-expected.txt
index 9393d80..5c40adbe 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
index 9393d80..5c40adbe 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-col-span-initial-empty-expected.txt
@@ -10,12 +10,12 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [59, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-expected.txt
index 5865cf1..2193cdb 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [58, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
index 5865cf1..2193cdb 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-colgroup-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD id='target'",
+      "name": "LayoutNGTableCell TD id='target'",
       "bounds": [58, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt
index c6e51b80..38747004 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
index c6e51b80..38747004 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-composited-row-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-expected.txt
index e6ec8ea..6f51a69 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
index e6ec8ea..6f51a69 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-initial-empty-expected.txt
@@ -10,7 +10,7 @@
       ]
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 1
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
index 333a368..3da4872 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
index 333a368..3da4872 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-composited-row-initial-empty-expected.txt
@@ -20,7 +20,7 @@
       "transform": 2
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 3
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt
index 444f4cd..61d07af 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
index 444f4cd..61d07af 100644
--- a/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
+++ b/third_party/blink/web_tests/platform/win/paint/invalidation/table/composited-table-background-section-initial-empty-expected.txt
@@ -15,7 +15,7 @@
       "transform": 1
     },
     {
-      "name": "LayoutNGTableCellNew TD",
+      "name": "LayoutNGTableCell TD",
       "bounds": [58, 64],
       "transform": 2
     }
diff --git a/third_party/blink/web_tests/platform/win/svg/foreignObject/svg-document-in-html-document-expected.png b/third_party/blink/web_tests/platform/win/svg/foreignObject/svg-document-in-html-document-expected.png
index 6114c97..35558fb 100644
--- a/third_party/blink/web_tests/platform/win/svg/foreignObject/svg-document-in-html-document-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/foreignObject/svg-document-in-html-document-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-foreignObject-expected.png b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-foreignObject-expected.png
index cf3aa95..1830887 100644
--- a/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-foreignObject-expected.png
+++ b/third_party/blink/web_tests/platform/win/svg/zoom/page/zoom-foreignObject-expected.png
Binary files differ
diff --git a/third_party/blink/web_tests/svg/text/pre-wrap-margin-crash.html b/third_party/blink/web_tests/svg/text/pre-wrap-crash.html
similarity index 74%
rename from third_party/blink/web_tests/svg/text/pre-wrap-margin-crash.html
rename to third_party/blink/web_tests/svg/text/pre-wrap-crash.html
index 1c97670..31c05f1 100644
--- a/third_party/blink/web_tests/svg/text/pre-wrap-margin-crash.html
+++ b/third_party/blink/web_tests/svg/text/pre-wrap-crash.html
@@ -5,8 +5,12 @@
 <body>
 <svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="515" height="375">
   <g>
+    <!-- crbug.com/1246807 -->
     <text x="71" y="98"><tspan>	d@@FP00:00</tspan></text>
   </g>
+  <!-- crbug.com/1250929 -->
+  <text x="5" y="40" font-family="Arial" font-size="40" style="border-inline-end: 2147483467px solid lime;">
+  Foo bar baz</text>
 </svg>
 <style>
 tspan {
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt
index 0c9933a..92bfa200 100644
--- a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt
+++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/RTCPeerConnection-restartIce.https-expected.txt
@@ -1,4 +1,5 @@
 This is a testharness.js-based test.
+PASS restartIce() has no effect on a closed peer connection
 FAIL restartIce() does not trigger negotiation ahead of initial negotiation assert_equals: No negotiationneeded event expected (undefined) undefined but got (object) object "[object Event]"
 FAIL restartIce() has no effect on initial negotiation promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
 FAIL restartIce() fires negotiationneeded after initial negotiation promise_test: Unhandled rejection with value: object "InvalidStateError: Failed to execute 'addTransceiver' on 'RTCPeerConnection': This operation is only supported in 'unified-plan'."
diff --git a/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/no-media-call-expected.txt b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/no-media-call-expected.txt
new file mode 100644
index 0000000..3961ea0
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/webrtc-wpt-plan-b/external/wpt/webrtc/no-media-call-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL Can set up a basic WebRTC call with no data. assert_equals: expected (number) 1 but got (undefined) undefined
+Harness: the test ran to completion.
+
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 74c7e683c..24e71da 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -98,6 +98,7 @@
       # running on CQ.
       'android-pie-arm64-coverage-experimental-rel': 'android_release_bot_arm64_webview_google_expectations',
       'android-pie-arm64-rel': 'android_release_bot_minimal_symbols_arm64_webview_google',
+      'android-pie-arm64-rel-rts': 'android_release_bot_minimal_symbols_arm64_webview_google',
       'android-pie-x86-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_webview_google',
       'android-weblayer-with-aosp-webview-x86-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_resource_allowlisting_disable_proguard_chrome_google',
       'android-weblayer-x86-rel': 'android_release_bot_minimal_symbols_x86_fastbuild_disable_proguard_webview_google',
@@ -1050,6 +1051,7 @@
       'linux-xenial-rel': 'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange',
       'linux_chromium_archive_rel_ng': 'release_bot',
       'linux_chromium_asan_rel_ng': 'asan_lsan_release_trybot',
+      'linux_chromium_asan_rel_ng_rts': 'asan_lsan_release_trybot',
       'linux_chromium_cfi_rel_ng': 'cfi_full_cfi_icall_cfi_diag_thin_lto_release_static_dcheck_always_on_goma',
       'linux_chromium_chromeos_asan_rel_ng': 'asan_lsan_chromeos_release_trybot',
       'linux_chromium_chromeos_msan_rel_ng': 'chromeos_msan_release_bot',
@@ -1066,6 +1068,7 @@
       'linux_chromium_msan_rel_ng': 'msan_release_bot',
 
       'linux_chromium_tsan_rel_ng': 'tsan_disable_nacl_release_trybot',
+      'linux_chromium_tsan_rel_ng_rts': 'tsan_disable_nacl_release_trybot',
 
       # This is intentionally a release_bot and not a release_trybot to match
       # the CI configuration, where no debug builder exists.
@@ -1128,7 +1131,7 @@
       'mac_upload_clang': 'release_bot',
       'mac_upload_clang_arm': 'release_bot',
       'mac-inverse-fieldtrials-fyi-rel': 'gpu_tests_release_trybot_invert_fieldtrials',
-      'mac-rel': 'gpu_tests_release_trybot_no_symbols',
+      'mac-rel': 'gpu_tests_release_trybot_no_symbols_mac_code_coverage',
       'mac-rel-rts': 'gpu_tests_release_trybot_no_symbols',
       'mac11-arm64-rel': 'mac_arm64_release_trybot',
     },
@@ -2360,6 +2363,11 @@
       'gpu_tests', 'release_trybot', 'no_symbols',
     ],
 
+    'gpu_tests_release_trybot_no_symbols_mac_code_coverage': [
+      'gpu_tests', 'release_trybot', 'no_symbols',
+      'use_clang_coverage', 'partial_code_coverage_instrumentation'
+    ],
+
     'gpu_tests_release_trybot_no_symbols_use_dummy_lastchange': [
       'gpu_tests', 'release_trybot', 'no_symbols', 'use_dummy_lastchange',
     ],
@@ -3636,12 +3644,12 @@
     },
 
     'reclient': {
-      'gn_args': 'use_rbe=true',
+      'gn_args': 'use_rbe=true use_remoteexec=true',
     },
 
     # experiment windows cross. crbug.com/1213717
     'reclient_win_cross': {
-      'gn_args': 'use_rbe=true rbe_cfg_dir="../../buildtools/reclient_cfgs/win-cross-experiments"',
+      'gn_args': 'use_rbe=true use_remoteexec=true rbe_cfg_dir="../../buildtools/reclient_cfgs/win-cross-experiments"',
     },
 
     # Historically, a 'release' bot had DCHECKs turned off. DCHECKs are now
diff --git a/tools/mb/mb_config_expectations/chromium.android.fyi.json b/tools/mb/mb_config_expectations/chromium.android.fyi.json
index 6c06eae..bcdb025d 100644
--- a/tools/mb/mb_config_expectations/chromium.android.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.android.fyi.json
@@ -10,7 +10,8 @@
       "strip_debug_info": true,
       "symbol_level": 1,
       "target_os": "android",
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Android WebView P FYI (rel)": {
@@ -38,7 +39,8 @@
       "system_webview_package_name": "com.google.android.webview",
       "target_cpu": "arm64",
       "target_os": "android",
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "android-12-x64-fyi-rel": {
diff --git a/tools/mb/mb_config_expectations/chromium.android.json b/tools/mb/mb_config_expectations/chromium.android.json
index 59931af0..10071c05 100644
--- a/tools/mb/mb_config_expectations/chromium.android.json
+++ b/tools/mb/mb_config_expectations/chromium.android.json
@@ -531,6 +531,21 @@
       "use_goma": true
     }
   },
+  "android-pie-arm64-rel-rts": {
+    "gn_args": {
+      "dcheck_always_on": false,
+      "ffmpeg_branding": "Chrome",
+      "is_component_build": false,
+      "is_debug": false,
+      "proprietary_codecs": true,
+      "strip_debug_info": true,
+      "symbol_level": 1,
+      "system_webview_package_name": "com.google.android.webview",
+      "target_cpu": "arm64",
+      "target_os": "android",
+      "use_goma": true
+    }
+  },
   "android-pie-x86-rel": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 72c69a0d..5d0abe0 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -6,7 +6,8 @@
       "is_debug": true,
       "is_lsan": true,
       "symbol_level": 1,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Afl Upload Linux ASan": {
@@ -40,7 +41,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Libfuzzer Upload Chrome OS ASan": {
@@ -89,7 +91,8 @@
       "pdf_enable_xfa": true,
       "proprietary_codecs": true,
       "use_libfuzzer": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Libfuzzer Upload Linux ASan Debug": {
@@ -189,7 +192,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Linux Builder (deps-cache) (reclient)": {
@@ -199,7 +203,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Linux Builder (j-500) (g-ip) (reclient)": {
@@ -209,7 +214,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Linux Builder (j-500) (n2) (reclient)": {
@@ -219,7 +225,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Linux Builder (j-500) (reclient)": {
@@ -229,7 +236,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Linux TSan Builder (goma cache silo)": {
@@ -249,7 +257,8 @@
       "is_component_build": false,
       "is_debug": false,
       "is_tsan": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Linux Viz": {
@@ -270,7 +279,8 @@
       "is_debug": false,
       "proprietary_codecs": true,
       "symbol_level": 1,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Mac Builder Next": {
@@ -323,7 +333,8 @@
       "is_debug": true,
       "is_tsan": true,
       "symbol_level": 1,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "TSAN Release (core-32) (goma)": {
@@ -343,7 +354,8 @@
       "is_component_build": false,
       "is_debug": false,
       "is_tsan": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "TSAN Release (deps-cache) (reclient)": {
@@ -353,7 +365,8 @@
       "is_component_build": false,
       "is_debug": false,
       "is_tsan": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "TSAN Release (g-ip) (reclient)": {
@@ -363,7 +376,8 @@
       "is_component_build": false,
       "is_debug": false,
       "is_tsan": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "TSAN Release (j-250) (reclient)": {
@@ -373,7 +387,8 @@
       "is_component_build": false,
       "is_debug": false,
       "is_tsan": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "TSAN Release (reclient)": {
@@ -383,7 +398,8 @@
       "is_component_build": false,
       "is_debug": false,
       "is_tsan": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "UBSan Release (reclient)": {
@@ -392,7 +408,8 @@
       "is_component_build": false,
       "is_debug": false,
       "is_ubsan": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "VR Linux": {
@@ -412,7 +429,8 @@
       "is_component_build": false,
       "is_debug": false,
       "use_ozone": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Win 10 Fast Ring": {
@@ -433,7 +451,8 @@
       "is_debug": false,
       "proprietary_codecs": true,
       "symbol_level": 1,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Win x64 Builder (reclient)(cross)": {
@@ -445,7 +464,8 @@
       "proprietary_codecs": true,
       "rbe_cfg_dir": "../../buildtools/reclient_cfgs/win-cross-experiments",
       "symbol_level": 1,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "android-backuprefptr-arm-fyi-rel": {
@@ -559,7 +579,8 @@
       "is_chromeos_device": true,
       "ozone_platform_headless": true,
       "use_rbe": true,
-      "use_real_dbus_clients": false
+      "use_real_dbus_clients": false,
+      "use_remoteexec": true
     }
   },
   "chromeos-amd64-generic-rel (reclient)": {
@@ -568,7 +589,8 @@
       "is_chromeos_device": true,
       "ozone_platform_headless": true,
       "use_rbe": true,
-      "use_real_dbus_clients": false
+      "use_real_dbus_clients": false,
+      "use_remoteexec": true
     }
   },
   "chromeos-amd64-generic-rel-dchecks": {
@@ -825,7 +847,8 @@
       "is_chromeos_device": true,
       "ozone_platform_headless": true,
       "target_os": "chromeos",
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "lacros-amd64-generic-rel-fyi": {
@@ -1021,7 +1044,8 @@
       "is_component_build": false,
       "is_debug": false,
       "target_os": "chromeos",
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "linux-lacros-code-coverage": {
diff --git a/tools/mb/mb_config_expectations/chromium.reclient.fyi.json b/tools/mb/mb_config_expectations/chromium.reclient.fyi.json
index b201879..400c0404 100644
--- a/tools/mb/mb_config_expectations/chromium.reclient.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.reclient.fyi.json
@@ -6,7 +6,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "Linux Builder reclient test": {
@@ -16,7 +17,8 @@
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   }
 }
\ No newline at end of file
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
index afb4dbb..971545d 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.linux.json
@@ -753,7 +753,8 @@
       "symbol_level": 0,
       "use_clang_coverage": true,
       "use_dummy_lastchange": true,
-      "use_rbe": true
+      "use_rbe": true,
+      "use_remoteexec": true
     }
   },
   "linux-rel-rts": {
@@ -867,6 +868,18 @@
       "use_goma": true
     }
   },
+  "linux_chromium_asan_rel_ng_rts": {
+    "gn_args": {
+      "blink_enable_generated_code_formatting": false,
+      "dcheck_always_on": true,
+      "is_asan": true,
+      "is_component_build": false,
+      "is_debug": false,
+      "is_lsan": true,
+      "symbol_level": 1,
+      "use_goma": true
+    }
+  },
   "linux_chromium_cfi_rel_ng": {
     "gn_args": {
       "dcheck_always_on": true,
@@ -983,6 +996,18 @@
       "use_goma": true
     }
   },
+  "linux_chromium_tsan_rel_ng_rts": {
+    "gn_args": {
+      "blink_enable_generated_code_formatting": false,
+      "dcheck_always_on": true,
+      "enable_nacl": false,
+      "is_component_build": false,
+      "is_debug": false,
+      "is_tsan": true,
+      "symbol_level": 1,
+      "use_goma": true
+    }
+  },
   "linux_chromium_ubsan_rel_ng": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
index 550cabd..3533624 100644
--- a/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
+++ b/tools/mb/mb_config_expectations/tryserver.chromium.mac.json
@@ -444,12 +444,14 @@
   "mac-rel": {
     "gn_args": {
       "blink_enable_generated_code_formatting": false,
+      "coverage_instrumentation_input_file": "//.code-coverage/files_to_instrument.txt",
       "dcheck_always_on": true,
       "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
       "proprietary_codecs": true,
       "symbol_level": 0,
+      "use_clang_coverage": true,
       "use_goma": true
     }
   },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index c0be5e1a..c8383d66 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -49060,6 +49060,7 @@
   <int value="-825747847"
       label="AutofillEnableSupportForMoreStructureInAddresses:enabled"/>
   <int value="-825312041" label="CastStreamingAv1:enabled"/>
+  <int value="-824829316" label="UsbDeviceDefaultAttachToArcVm:enabled"/>
   <int value="-824199802" label="ContextualSearchSimplifiedServer:enabled"/>
   <int value="-823394398" label="TargetEmbeddingLookalikes:enabled"/>
   <int value="-823165021" label="MaterialDesignUserMenu:enabled"/>
@@ -51929,6 +51930,7 @@
   <int value="1429031731"
       label="CrossOriginEmbedderPolicyCredentialless:enabled"/>
   <int value="1429923065" label="enable-media-internals:enabled"/>
+  <int value="1430421070" label="UsbDeviceDefaultAttachToArcVm:disabled"/>
   <int value="1430924529" label="TranslateIntent:enabled"/>
   <int value="1431050645" label="PayWithGoogleV1:disabled"/>
   <int value="1431934725" label="OmniboxAutocompleteTitles:disabled"/>
@@ -64019,6 +64021,7 @@
   <int value="3" label="Unlock account-store to fill password"/>
   <int value="4" label="Unlock account-store to generate password"/>
   <int value="5" label="Re-Signin to unlock account-stored passwords"/>
+  <int value="6" label="WebAuthn credential"/>
 </enum>
 
 <enum name="PasswordDropdownState">
@@ -76116,8 +76119,11 @@
   <int value="4" label="SharedClipboard"/>
   <int value="5" label="SmsFetchRequest"/>
   <int value="6" label="RemoteCopy"/>
-  <int value="7" label="SignallingMessage"/>
-  <int value="8" label="IceCandidateMessage"/>
+  <int value="7" label="PeerConnectionOffer"/>
+  <int value="8" label="PeerConnectionIceCandidate"/>
+  <int value="9" label="DiscoveryRequest"/>
+  <int value="10" label="WebRTCSignalingFrame"/>
+  <int value="11" label="OptimizationGuidePushNotification"/>
 </enum>
 
 <enum name="SharingRemoteCopyHandleMessageResult">
@@ -88676,6 +88682,7 @@
   <int value="24" label="Safety tip help opened"/>
   <int value="25" label="Chooser object deleted"/>
   <int value="26" label="Reset certificate decisions clicked"/>
+  <int value="27" label="Store info clicked"/>
 </enum>
 
 <enum name="WebSiteSettingsAllSitesAction">
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index 425f69de..6981d7a 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -16526,13 +16526,19 @@
 <histogram_suffixes name="SharingMessage" separator=".">
   <suffix name="ACK_MESSAGE" label="Ack Message"/>
   <suffix name="CLICK_TO_CALL_MESSAGE" label="Click To Call Message"/>
-  <suffix name="ICE_CANDIDATE_MESSAGE" label="Ice Candidate Message"/>
+  <suffix name="DISCOVERY_REQUEST" label="Discovery Request Message"/>
+  <suffix name="OPTIMIZATION_GUIDE_PUSH_NOTIFICATION"
+      label="Optimization Guide Push Notification Message"/>
+  <suffix name="PEER_CONNECTION_ICE_CANDIDATES_MESSAGE"
+      label="Peer Connection Ice Candidates Message"/>
+  <suffix name="PEER_CONNECTION_OFFER_MESSAGE"
+      label="Peer Connection Offer Message"/>
   <suffix name="PING_MESSAGE" label="Ping Message"/>
   <suffix name="REMOTE_COPY_MESSAGE" label="Remote Copy Message"/>
   <suffix name="SHARED_CLIPBOARD_MESSAGE" label="Shared Clipboard Message"/>
-  <suffix name="SIGNALLING_MESSAGE" label="Signalling Message"/>
   <suffix name="SMS_FETCH_REQUEST" label="SMS Fetch Request"/>
   <suffix name="UNKNOWN_MESSAGE" label="Unknown Message"/>
+  <suffix name="WEB_RTC_SIGNALING_FRAME" label="Web RTC Signalling Message"/>
   <affected-histogram name="Sharing.DeviceLastUpdatedAge">
     <obsolete>
       Removed in M89.
diff --git a/tools/metrics/histograms/metadata/history/histograms.xml b/tools/metrics/histograms/metadata/history/histograms.xml
index 8963314e..93dccdf 100644
--- a/tools/metrics/histograms/metadata/history/histograms.xml
+++ b/tools/metrics/histograms/metadata/history/histograms.xml
@@ -394,6 +394,27 @@
   </summary>
 </histogram>
 
+<histogram name="History.Clusters.ServiceLatency" units="ms"
+    expires_after="2022-02-25">
+  <owner>tommycli@chromium.org</owner>
+  <owner>chrome-memories@google.com</owner>
+  <summary>
+    Records the time taken between the History Clusters WebUI handler requests a
+    batch of clusters, and when we get the clusters back from the Service.
+
+    This request occurs when the page is first loaded, when the page is
+    refreshed, when the user changes the History search terms, and when the user
+    scrolls to the bottom of the page and requests the next batch of clusters
+    from the service.
+
+    This metric doesn't distinguish between any of these cases. This metric is
+    recorded on all requests, whether or not it returns clusters.
+
+    This does not take into account the time spent in JavaScript, or updating
+    the DOM.
+  </summary>
+</histogram>
+
 <histogram name="History.DatabaseAdvancedMetricsTime" units="ms"
     expires_after="M77">
   <owner>shess@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 1e100b7..57602a4 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,19 +6,19 @@
         },
         "win": {
             "hash": "c0ed1dac3cbdb4125dd767839049204911a7bec0",
-            "remote_path": "perfetto_binaries/trace_processor_shell/win/25498a007db7d4b1e1aef2b722aa1e54651b0288/trace_processor_shell.exe"
+            "remote_path": "perfetto_binaries/trace_processor_shell/win/18d0bcdb5c126006c04dfeceff3801aeaa10689f/trace_processor_shell.exe"
         },
         "mac": {
             "hash": "a179863f0b4737a329c86894e8bd22e7888249d4",
-            "remote_path": "perfetto_binaries/trace_processor_shell/mac/7095880cdb1f63e187ec319dcd0a8cd1b51f320f/trace_processor_shell"
+            "remote_path": "perfetto_binaries/trace_processor_shell/mac/18d0bcdb5c126006c04dfeceff3801aeaa10689f/trace_processor_shell"
         },
         "linux_arm64": {
             "hash": "5074025a2898ec41a872e70a5719e417acb0a380",
             "remote_path": "perfetto_binaries/trace_processor_shell/linux_arm64/49b4b5dcbc312d8d2c3751cf29238b8efeb4e494/trace_processor_shell"
         },
         "linux": {
-            "hash": "2339ea6488f19f4e167fe856fc534b0e67e00828",
-            "remote_path": "perfetto_binaries/trace_processor_shell/linux/25498a007db7d4b1e1aef2b722aa1e54651b0288/trace_processor_shell"
+            "hash": "af5144ebded815e04e9efaeec665e7b89556e34c",
+            "remote_path": "perfetto_binaries/trace_processor_shell/linux/18d0bcdb5c126006c04dfeceff3801aeaa10689f/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml
index 29745fa9..24602c9 100644
--- a/tools/traffic_annotation/summary/annotations.xml
+++ b/tools/traffic_annotation/summary/annotations.xml
@@ -13,6 +13,7 @@
  <item id="adb_client_socket" added_in_milestone="65" hash_code="87775794" type="0" content_hash_code="56654828" os_list="linux,windows" file_path="chrome/browser/devtools/device/adb/adb_client_socket.cc"/>
  <item id="affiliation_lookup" added_in_milestone="62" hash_code="111904019" type="0" deprecated="2021-07-27" content_hash_code="81061452" file_path=""/>
  <item id="affiliation_lookup_by_hash" added_in_milestone="87" hash_code="57748571" type="0" content_hash_code="40566404" os_list="linux,windows" file_path="components/password_manager/core/browser/site_affiliation/hash_affiliation_fetcher.cc"/>
+ <item id="aggregation_service_helper_keys" added_in_milestone="96" hash_code="49783589" type="0" content_hash_code="68319105" os_list="linux,windows" file_path="content/browser/aggregation_service/aggregation_service_network_fetcher_impl.cc"/>
  <item id="aggregation_service_report" added_in_milestone="95" hash_code="95942194" type="0" content_hash_code="44673922" os_list="linux,windows" file_path="content/browser/aggregation_service/aggregatable_report_sender.cc"/>
  <item id="android_device_manager_socket" added_in_milestone="65" hash_code="37249086" type="0" content_hash_code="6436865" os_list="linux,windows" file_path="chrome/browser/devtools/device/android_device_manager.cc"/>
  <item id="android_web_socket" added_in_milestone="65" hash_code="39356976" type="0" content_hash_code="12310113" os_list="linux,windows" file_path="chrome/browser/devtools/device/android_web_socket.cc"/>
diff --git a/tools/traffic_annotation/summary/grouping.xml b/tools/traffic_annotation/summary/grouping.xml
index 97b208d..cc50e3c 100644
--- a/tools/traffic_annotation/summary/grouping.xml
+++ b/tools/traffic_annotation/summary/grouping.xml
@@ -233,6 +233,7 @@
       <traffic_annotation unique_id="floc_event_logger"/>
     </sender>
     <sender name="Aggregation Service">
+      <traffic_annotation unique_id="aggregation_service_helper_keys"/>
       <traffic_annotation unique_id="aggregation_service_report"/>
     </sender>
   </group>
diff --git a/ui/android/java/res/values/attrs.xml b/ui/android/java/res/values/attrs.xml
index 2ab6766..e0e80d9 100644
--- a/ui/android/java/res/values/attrs.xml
+++ b/ui/android/java/res/values/attrs.xml
@@ -48,6 +48,9 @@
     <attr name="default_icon_color_secondary" format="color" />
     <attr name="default_icon_color_disabled" format="color" />
     <attr name="default_icon_color_disabled_inverse" format="color" />
+    <attr name="default_icon_color_accent1" format="color" />
+
+    <attr name="default_text_color_accent1" format="color" />
 
     <declare-styleable name="ButtonCompat">
         <!-- The color of the button background. -->
diff --git a/ui/base/clipboard/clipboard_test_template.h b/ui/base/clipboard/clipboard_test_template.h
index 409af3dc..5034eaa 100644
--- a/ui/base/clipboard/clipboard_test_template.h
+++ b/ui/base/clipboard/clipboard_test_template.h
@@ -122,10 +122,10 @@
                     const absl::optional<size_t> size,
                     content::RenderFrameHost* rfh,
                     base::OnceCallback<void(bool)> callback));
-  MOCK_METHOD3(IsDragDropAllowed,
-               bool(const DataTransferEndpoint* const data_src,
-                    const DataTransferEndpoint* const data_dst,
-                    const bool is_drop));
+  MOCK_METHOD3(DropIfAllowed,
+               void(const ui::DataTransferEndpoint* data_src,
+                    const ui::DataTransferEndpoint* data_dst,
+                    base::OnceClosure drop_cb));
 };
 
 MockPolicyController::MockPolicyController() = default;
diff --git a/ui/base/data_transfer_policy/data_transfer_policy_controller.h b/ui/base/data_transfer_policy/data_transfer_policy_controller.h
index 47fc9d2..0305abf9 100644
--- a/ui/base/data_transfer_policy/data_transfer_policy_controller.h
+++ b/ui/base/data_transfer_policy/data_transfer_policy_controller.h
@@ -52,10 +52,14 @@
                               base::OnceCallback<void(bool)> callback) = 0;
 
   // nullptr can be passed instead of `data_src` or `data_dst`. If dropping the
-  // data is not allowed, this function will show a notification to the user.
-  virtual bool IsDragDropAllowed(const DataTransferEndpoint* data_src,
-                                 const DataTransferEndpoint* data_dst,
-                                 bool is_drop) = 0;
+  // data is not allowed, this function will show a notification to the user. If
+  // the drop is allowed, `drop_cb` will be run. Otherwise `drop_cb` will be
+  // reset.
+  // `drop_cb` may be run asynchronously after the user comfirms they want to
+  // drop the data.
+  virtual void DropIfAllowed(const DataTransferEndpoint* data_src,
+                             const DataTransferEndpoint* data_dst,
+                             base::OnceClosure drop_cb) = 0;
 
  protected:
   DataTransferPolicyController();
diff --git a/ui/base/interaction/interaction_sequence.cc b/ui/base/interaction/interaction_sequence.cc
index 8c5597e7..e1357995 100644
--- a/ui/base/interaction/interaction_sequence.cc
+++ b/ui/base/interaction/interaction_sequence.cc
@@ -136,10 +136,14 @@
   DCHECK(step->id);
   DCHECK(configuration_->steps.empty() || !step->element)
       << " Only the initial step of a sequence may have a pre-set element.";
+  DCHECK(!step->transition_only_on_event || !step->element)
+      << " Pre-set element precludes transition_only_on_event.";
   step->must_be_visible =
       step->must_be_visible.value_or(step->type == StepType::kActivated);
   DCHECK(!step->element || step->must_be_visible.value())
       << " Initial step with associated element must be visible from start.";
+  DCHECK(!step->transition_only_on_event || !step->must_be_visible.value())
+      << " must_be_visible is not compatible with transition_only_on_event.";
   DCHECK(step->type != InteractionSequence::StepType::kHidden ||
          !step->must_remain_visible.has_value() ||
          !step->must_remain_visible.value());
@@ -208,6 +212,13 @@
   return *this;
 }
 
+InteractionSequence::StepBuilder&
+InteractionSequence::StepBuilder::SetTransitionOnlyOnEvent(
+    bool transition_only_on_event) {
+  step_->transition_only_on_event = transition_only_on_event;
+  return *this;
+}
+
 InteractionSequence::StepBuilder& InteractionSequence::StepBuilder::SetType(
     StepType step_type) {
   step_->type = step_type;
@@ -481,7 +492,7 @@
 
   switch (next_step()->type) {
     case StepType::kShown:
-      if (next_element) {
+      if (next_element && !next_step()->transition_only_on_event) {
         DoStepTransition(next_element);
       } else {
         next_step()->subscription = tracker->AddElementShownCallback(
@@ -491,7 +502,7 @@
       }
       break;
     case StepType::kHidden:
-      if (!next_element) {
+      if (!next_element && !next_step()->transition_only_on_event) {
         DoStepTransition(nullptr);
       } else {
         next_step()->subscription = tracker->AddElementHiddenCallback(
diff --git a/ui/base/interaction/interaction_sequence.h b/ui/base/interaction/interaction_sequence.h
index 83013ab..3b53793 100644
--- a/ui/base/interaction/interaction_sequence.h
+++ b/ui/base/interaction/interaction_sequence.h
@@ -60,12 +60,13 @@
   // The type of event that is expected to happen next in the sequence.
   enum class StepType {
     // Represents the element with the specified ID becoming visible to the
-    // user.
+    // user, or already being visible when the step starts.
     kShown,
     // Represents an element with the specified ID becoming activated by the
     // user (for buttons or menu items, being clicked).
     kActivated,
-    // Represents an element with the specified ID becoming hidden or destroyed.
+    // Represents an element with the specified ID becoming hidden or
+    // destroyed, or no elements with the specified ID being visible.
     kHidden
   };
 
@@ -117,6 +118,7 @@
     // appropriate defaults for `type`.
     absl::optional<bool> must_be_visible;
     absl::optional<bool> must_remain_visible;
+    bool transition_only_on_event = false;
 
     StepCallback start_callback;
     StepCallback end_callback;
@@ -194,6 +196,25 @@
     // condition will abort the sequence.
     StepBuilder& SetMustRemainVisible(bool must_remain_visible);
 
+    // For kShown and kHidden events, if set to true, only allows a step
+    // transition to happen when a "shown" or "hidden" event is received, and
+    // not if an element is already visible (in the case of kShown steps) or no
+    // elements are visible (in the case of kHidden steps).
+    //
+    // Default is false. Has no effect on kActiated events which are discrete
+    // rather than stateful.
+    //
+    // Note: Does not track events fired during previous step's start callback,
+    // so should not be used in automated interaction testing. The default
+    // behavior should be fine for these cases.
+    //
+    // Note: Be careful when setting this value to true, as it increases the
+    // likelihood of ending up in a state where a failure cannot be detected;
+    // that is, waiting for an element to appear and then it... never does. In
+    // this case, you will need an external way to terminate the sequence (a
+    // timeout, user interaction, etc.)
+    StepBuilder& SetTransitionOnlyOnEvent(bool transition_only_on_event);
+
     // Sets the callback called at the start of the step.
     StepBuilder& SetStartCallback(StepCallback start_callback);
 
diff --git a/ui/base/interaction/interaction_sequence_unittest.cc b/ui/base/interaction/interaction_sequence_unittest.cc
index ec384a6..50376649 100644
--- a/ui/base/interaction/interaction_sequence_unittest.cc
+++ b/ui/base/interaction/interaction_sequence_unittest.cc
@@ -1518,6 +1518,97 @@
       element3.Hide());
 }
 
+// SetTransitionOnlyOnEvent tests:
+
+TEST(InteractionSequenceTest,
+     SetTransitionOnlyOnEvent_TransitionsOnDifferentElementShown) {
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted);
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed);
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::StepCallback, step_start);
+  // Two elements have the same identifier, but only the first is visible.
+  TestElement element1(kTestIdentifier1, kTestContext1);
+  TestElement element2(kTestIdentifier1, kTestContext1);
+  element1.Show();
+  auto tracker =
+      InteractionSequence::Builder()
+          .SetAbortedCallback(aborted.Get())
+          .SetCompletedCallback(completed.Get())
+          .AddStep(InteractionSequence::WithInitialElement(&element1))
+          .AddStep(InteractionSequence::StepBuilder()
+                       .SetElementID(element2.identifier())
+                       .SetType(InteractionSequence::StepType::kShown)
+                       .SetTransitionOnlyOnEvent(true)
+                       .SetStartCallback(step_start.Get())
+                       .Build())
+          .Build();
+
+  tracker->Start();
+
+  // Fail step four.
+  EXPECT_CALLS_IN_SCOPE_2(step_start, Run, completed, Run, element2.Show());
+}
+
+TEST(InteractionSequenceTest,
+     SetTransitionOnlyOnEvent_TransitionsOnSameElementShown) {
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted);
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed);
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::StepCallback, step_start);
+  TestElement element1(kTestIdentifier1, kTestContext1);
+  element1.Show();
+  auto tracker =
+      InteractionSequence::Builder()
+          .SetContext(element1.context())
+          .SetAbortedCallback(aborted.Get())
+          .SetCompletedCallback(completed.Get())
+          .AddStep(InteractionSequence::StepBuilder()
+                       .SetElementID(element1.identifier())
+                       .SetType(InteractionSequence::StepType::kShown)
+                       .SetMustBeVisibleAtStart(true)
+                       .SetMustRemainVisible(false)
+                       .Build())
+          .AddStep(InteractionSequence::StepBuilder()
+                       .SetElementID(element1.identifier())
+                       .SetType(InteractionSequence::StepType::kShown)
+                       .SetTransitionOnlyOnEvent(true)
+                       .SetStartCallback(step_start.Get())
+                       .Build())
+          .Build();
+
+  tracker->Start();
+  element1.Hide();
+
+  // Fail step four.
+  EXPECT_CALLS_IN_SCOPE_2(step_start, Run, completed, Run, element1.Show());
+}
+
+TEST(InteractionSequenceTest,
+     SetTransitionOnlyOnEvent_TransitionsOnElementHidden) {
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::AbortedCallback, aborted);
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::CompletedCallback, completed);
+  UNCALLED_MOCK_CALLBACK(InteractionSequence::StepCallback, step_start);
+  TestElement element1(kTestIdentifier1, kTestContext1);
+  TestElement element2(kTestIdentifier2, kTestContext1);
+  element1.Show();
+  auto tracker =
+      InteractionSequence::Builder()
+          .SetAbortedCallback(aborted.Get())
+          .SetCompletedCallback(completed.Get())
+          .AddStep(InteractionSequence::WithInitialElement(&element1))
+          .AddStep(InteractionSequence::StepBuilder()
+                       .SetElementID(element2.identifier())
+                       .SetType(InteractionSequence::StepType::kHidden)
+                       .SetTransitionOnlyOnEvent(true)
+                       .SetStartCallback(step_start.Get())
+                       .Build())
+          .Build();
+
+  tracker->Start();
+  element2.Show();
+
+  // Fail step four.
+  EXPECT_CALLS_IN_SCOPE_2(step_start, Run, completed, Run, element2.Hide());
+}
+
 // RunSynchronouslyForTesting() tests:
 
 TEST(InteractionSequenceTest,
diff --git a/weblayer/browser/feature_list_creator.cc b/weblayer/browser/feature_list_creator.cc
index 3161b836..d028124 100644
--- a/weblayer/browser/feature_list_creator.cc
+++ b/weblayer/browser/feature_list_creator.cc
@@ -6,7 +6,6 @@
 
 #include "base/base_switches.h"
 #include "build/build_config.h"
-#include "cc/base/switches.h"
 #include "components/metrics/metrics_state_manager.h"
 #include "components/prefs/pref_service.h"
 #include "components/variations/service/variations_service.h"
@@ -80,8 +79,7 @@
   // Extended Variations Safe Mode experiment.
   // TODO(crbug/1245347): Enable the experiment on Android WebLayer.
   variations_service_->SetupFieldTrials(
-      cc::switches::kEnableGpuBenchmarking, switches::kEnableFeatures,
-      switches::kDisableFeatures, variation_ids,
+      variation_ids,
       content::GetSwitchDependentFeatureOverrides(
           *base::CommandLine::ForCurrentProcess()),
       std::move(feature_list), &weblayer_field_trials_,